在我的代码中,我有一个循环,在这个循环中,我向远程 Web 服务发送了几个请求。WS 提供商说:“Web 服务最多可以托管n 个线程”,所以我需要限制我的代码,因为我不能发送n+1 个线程。
如果我要发送m个线程,我希望前n 个线程将立即执行,一旦其中一个线程完成,将执行一个新线程(剩余的mn个线程之一),依此类推,直到所有m个线程都被执行.
我想到了一个线程池并将最大线程数显式设置为n。这够了吗?
在我的代码中,我有一个循环,在这个循环中,我向远程 Web 服务发送了几个请求。WS 提供商说:“Web 服务最多可以托管n 个线程”,所以我需要限制我的代码,因为我不能发送n+1 个线程。
如果我要发送m个线程,我希望前n 个线程将立即执行,一旦其中一个线程完成,将执行一个新线程(剩余的mn个线程之一),依此类推,直到所有m个线程都被执行.
我想到了一个线程池并将最大线程数显式设置为n。这够了吗?
为此,我会避免使用多个线程。相反,将整个循环包装起来,可以在单个线程上运行。但是,如果您确实想使用 /a 线程池启动多个线程,那么我将使用Semaphore
该类来促进所需的线程限制;就是这样...
信号量就像一个普通的夜总会保镖,它已经提供了一个俱乐部容量并且不允许超过这个限制。一旦俱乐部坐满了,就没有其他人可以进入了……外面已经排起了长队。然后当一个人离开时,另一个人可以进入(感谢 J. Albahari 的类比)。
值为 1 的ASemaphore
等价于 aMutex
或Lock
,只是它Semaphore
没有所有者,因此它是线程无知的。任何线程都可以使用 / 调用aRelease
而Semaphore
只有获得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
.