每次执行N个线程的最佳实践是什么?
本文关键字:最佳 是什么 线程 执行 | 更新日期: 2023-09-27 18:08:03
我有很多线程,如果我让。net运行时决定同时运行多少线程,它通常会触发OutOfMemoryException,因为操作真的很繁重。
每次请求到达我的服务器时,我都需要运行一个线程。我想做一个ThreadPool.EnqueueWorkItem
,但是说:请不要在给定时间内运行超过2个。等待其中一个完成后再开始下一个。
这种情况下的最佳实践是什么
使用ThreadPool.SetMaxThreads
方法
:
设置线程池中可以活动的请求数同时。所有超过该数字的请求都保持排队,直到线程池中的线程可用。
重要讲话:
如果公共语言运行库托管,例如通过Internet信息服务(IIS)或SQL Server,主机可以限制或防止更改线程池大小。请谨慎使用线程池中的最大线程数。虽然你的代码可能好处是,这些更改可能会对代码库产生不利影响你使用。将线程池大小设置得太大可能会影响性能问题。如果同时执行的线程太多,任务将无法执行切换开销成为一个重要因素。
此外,由于您提到了OutOfMemoryException
,请尝试释放未使用的资源(例如,如果可用,调用Dispose()
)。
更新:
正如@erikH所评论的,重要的是要注意,这种能力将限制整个线程池,但如果是一个更大的应用程序的一部分,当一些繁重的任务需要所有可用的线程池线程时,这也将限制所有的快速任务。
我会这样写
static int MAX_THREADS = 3;
static SemaphoreSlim _Semaphore = new SemaphoreSlim(MAX_THREADS, MAX_THREADS);
void ProcessRequest(Action action)
{
_Semaphore.Wait();
Task.Run(action)
.ContinueWith(t => _Semaphore.Release());
}
您应该使用例如AsyncSemaphore原语。
下面是代码(未测试):static readonly AsyncSemaphore s_semaphore = new AsyncSemaphore( 2 );
static async Task EnqueueAction( Action act )
{
await s_semaphore.WaitAsync();
try
{
await Task.Run( act );
}
finally
{
s_semaphore.Release();
}
}