2013-08-19 34 views
1

在我的代码中,我有一个循环,在这个循环内我向远程webservice发送了几个请求。 WS提供商表示:“该web服务最多可以承载n线程”,所以我需要限制我的代码,因为我无法发送n + 1线程。限制线程池中并发线程的数量

如果我送线程我会首先ň线程将被立即执行,并尽快其中之一是完成了一个新的线程(线程剩余MN之一)将被执行依此类推,直到所有的线程都被执行为止。我认为Thread Poolexplicit setting of the max thread number to n。这够了吗?

+0

为什么不包装整个for循环,以便单个后台线程池线程完成整个循环。这样你就不必担心线程的创建等。 – MoonKnight

+0

你真的是那个Web服务的唯一用户吗?异常。 –

+0

是的,唯一的用户。 –

回答

2

为此,我将避免使用多个线程。相反,包装整个循环可以在单个线程上运行。但是,如果您确实想使用/ a线程池启动多个线程,那么我会使用Semaphore类来简化所需的线程限制;这里是如何...

信号量就像一个平均夜总会保镖,它已经提供了一个俱乐部的容量,不能超过这个限制。一旦俱乐部满员,其他人都无法进入......队列在外面建立起来。然后当一个人离开另一个人时可以进入(比喻感谢J. Albahari)。

Semaphore与一的值等同于MutexLock除了Semaphore没有所有者,使得它是线程无知。任何线程都可以在Semaphore上调用Release,而使用Mutex/Lock,只有获得了Mutex/Lock的线程才可以释放它。

现在,对于您的情况,我们可以使用Semaphore s来限制并发性并防止太多线程同时执行特定代码。在下面的例子中,五个线程尝试进入仅允许进入三个的夜总会...

class BadAssClub 
{ 
    static SemaphoreSlim sem = new SemaphoreSlim(3); 
    static void Main() 
    { 
     for (int i = 1; i <= 5; i++) 
      new Thread(Enter).Start(i); 
    } 

    // Enfore only three threads running this method at once. 
    static void Enter(int i) 
    { 
     try 
     { 
      Console.WriteLine(i + " wants to enter."); 
      sem.Wait(); 
      Console.WriteLine(i + " is in!"); 
      Thread.Sleep(1000 * (int)i); 
      Console.WriteLine(i + " is leaving..."); 
     } 
     finally 
     { 
      sem.Release(); 
     } 
    } 
} 

我希望这有助于。


编辑。您也可以使用ThreadPool.SetMaxThreads方法。该方法限制了允许在线程池中运行的线程数量。但它为线程池本身提供了“全局”功能。这意味着如果您在应用程序使用的库中运行SQL查询或其他方法,则由于此阻塞,新线程不会启动。这可能与您无关,在这种情况下请使用SetMaxThreads方法。如果您想阻止特定方法,则使用Semphores更安全。

+0

是的,这有帮助!你能解释一下ThreadPool.SetMaxThreads方法的用法吗?谢谢:) –

+0

PS:一个单线程将不是那么有用。导致WS响应花费大量时间,幸运的是,WS针对多个实例进行了优化,因此多个线程将完成这项工作! –

+0

设置可同时处于活动状态的线程池的请求数。在线程池线程可用之前,所有超出该数字的请求都保持排队。更改线程池中的最大线程数时请小心。虽然您的代码可能会受益,但这些更改可能会对您使用的代码库产生不利影响。 将线程池大小设置得过大可能会导致性能问题。如果太多线程同时执行,任务切换开销就成为一个重要因素。 – MoonKnight