1

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

如果我要发送m个线程,我希望前n 个线程将立即执行,一旦其中一个线程完成,将执行一个新线程(剩余的mn个线程之一),依此类推,直到所有m个线程都被执行.

我想到了一个线程池并将最大线程数显式设置为n。这够了吗?

4

1 回答 1

2

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

信号量就像一个普通的夜总会保镖,它已经提供了一个俱乐部容量并且不允许超过这个限制。一旦俱乐部坐满了,就没有其他人可以进入了……外面已经排起了长队。然后当一个人离开时,另一个人可以进入(感谢 J. Albahari 的类比)。

值为 1 的ASemaphore等价于 aMutexLock,只是它Semaphore没有所有者,因此它是线程无知的。任何线程都可以使用 / 调用aReleaseSemaphore只有获得Mutex/Lock的线程MutexLock的线程才能释放它。

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

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.

于 2013-08-19T09:54:29.017 回答