每次执行N个线程的最佳实践是什么?

本文关键字:最佳 是什么 线程 执行 | 更新日期: 2023-09-27 18:08:03

我有很多线程,如果我让。net运行时决定同时运行多少线程,它通常会触发OutOfMemoryException,因为操作真的很繁重。

每次请求到达我的服务器时,我都需要运行一个线程。我想做一个ThreadPool.EnqueueWorkItem,但是说:请不要在给定时间内运行超过2个。等待其中一个完成后再开始下一个。

这种情况下的最佳实践是什么

每次执行N个线程的最佳实践是什么?

使用ThreadPool.SetMaxThreads方法

从MSDN

:

设置线程池中可以活动的请求数同时。所有超过该数字的请求都保持排队,直到线程池中的线程可用。

重要讲话:

如果公共语言运行库托管,例如通过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();
    }
}