在我的代码中我有一个循环,在这个循环中我向远程webservice发送了几个请求。 WS提供商说:“webservice最多可以托管 n 线程”,所以我需要限制我的代码,因为我无法发送 n + 1 线程。
如果我要发送 m 线程,我会立即执行第一个 n 线程,并且很快就会完成其中一个线程(其中一个线程)剩余的 mn 线程)将被执行,依此类推,直到所有 m 线程被执行。
我想到了Thread Pool和explicit setting of the max thread number to n。这够了吗?
答案 0 :(得分:2)
为此我会避免使用多个线程。相反,将整个循环包装起来可以在单个线程上运行。但是,如果您确实想使用/ a线程池启动多个线程,那么我将使用Semaphore
类来促进所需的线程限制;这是怎么......
信号量就像一个卑鄙的夜总会保镖,它一直提供俱乐部容量,不允许超过这个限制。一旦俱乐部满员,没有其他人可以进入...队列在外面建立起来。然后当一个人离开时,另一个人可以进入(类比感谢J. Albahari)。
值为1的Semaphore
等同于Mutex
或Lock
,但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
会更安全。