限制线程池中的并发线程数

时间:2013-08-19 09:36:44

标签: multithreading threadpool

在我的代码中我有一个循环,在这个循环中我向远程webservice发送了几个请求。 WS提供商说:“webservice最多可以托管 n 线程”,所以我需要限制我的代码,因为我无法发送 n + 1 线程。

如果我要发送 m 线程,我会立即执行第一个 n 线程,并且很快就会完成其中一个线程(其中一个线程)剩余的 mn 线程)将被执行,依此类推,直到所有 m 线程被执行。

我想到了Thread Poolexplicit setting of the max thread number to n。这够了吗?

1 个答案:

答案 0 :(得分:2)

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

信号量就像一个卑鄙的夜总会保镖,它一直提供俱乐部容量,不允许超过这个限制。一旦俱乐部满员,没有其他人可以进入...队列在外面建立起来。然后当一个人离开时,另一个人可以进入(类比感谢J. Albahari)。

值为1的Semaphore等同于MutexLock,但Semaphore没有所有者,因此它是线程无知的。任何主题都可以在Release上调用Semaphore,而使用Mutex / Lock只有获得Mutex / Lock的主题可以释放它

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

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会更安全。