ThreadPool线程需要等待

本文关键字:等待 线程 ThreadPool | 更新日期: 2023-09-27 18:23:37

我有一个应用程序,需要处理大量的消息(例如:每秒2000条)。业务需求要求我不要立即处理消息,而是等待2秒钟来处理每一条消息。我现在所做的是通过Task.Factory.StartNew为每条消息从线程池中剥离一个线程,并在线程池中的线程内完成"等待2秒"的工作。问题是,当消息负载非常高时,我总是会出现OutOfMemory异常,尽管根据Windows操作系统的任务管理器,内存消耗实际上并没有那么高。然而,如果我不在线程内等待,那么一切都很好。

我的猜测是,当消息负载很高时,线程池线程不足以处理所有消息。因此,越来越多的消息排队等待处理,当队列大小变得非常大时,就会导致OOM异常。已经尝试过ThreadPool.SetMaxThreads和ThreadPool.Set MinThreads达到非常高的数量,但仍然不起作用。有什么建议吗?

代码如下:

 ThreadPool.SetMaxThreads(32768, 32768);
 ThreadPool.SetMinThreads(2500, 2500);
public void HanldeMessage(string message)
{
     Task.Factory.StartNew(() => DoWork(message))
}
public void DoWork(string message)
{
   Thread.Sleep(2000);
   // do some work to message
}

ThreadPool线程需要等待

试试这个。您需要.NET 4.5。

private static void HandleMessage(string message)
{
    DoWork(message);
}
private static async Task DoWork(string message)
{
    await Task.Delay(2000); // instead of thread.Sleep
    // do some work...
    Console.WriteLine(message);
}

这应该有效地将线程返回到池中2秒钟,然后返回执行,而不是阻塞thread.sleep。

我建议您不要阻塞线程,尤其是在处理可能需要数千个线程的场景时。我还建议你不要设置ThreadPool.MaxThreads/MinThreads。你在这里对它进行了很多滥用。

每个线程占用1MB的堆栈空间。我敢打赌,你看到OOM异常的原因是因为你创建了太多线程,而不是因为排队请求创建线程。你上面的情况很糟糕,因为在完成了创建线程的所有工作后,它只会静止并腐烂2秒钟。需要做更多的工作,线程池通过创建另一个线程池来尽其所能提供帮助。随着你期望的请求量的增加,内存成为障碍只是时间问题。