【问题标题】:ThreadPool Thread needs to waitThreadPool 线程需要等待
【发布时间】:2013-07-15 19:01:20
【问题描述】:

我有一个需要处理大量消息的应用程序(例如:每秒 2000 条)。并且业务需求要求我不是立即处理消息,而是等待2秒来处理每条消息。我现在正在做的是通过 Task.Factory.StartNew 为每条消息从线程池中分离一个线程,并在池中的线​​程内执行“等待 2 秒”的工作。问题是当消息负载非常高时,我总是得到 OutOfMemory 异常,尽管根据 Windows 操作系统的任务管理器,内存消耗实际上并没有那么高。但是,如果我不在线程内等待,那么一切正常。

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

代码如下所示:

 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
}

【问题讨论】:

标签: c# .net task-parallel-library threadpool


【解决方案1】:

试试这个。您将需要 .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);
}

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

我建议您不要阻塞线程,尤其是在处理可能需要数千个线程的情况时。我还建议您不要设置 ThreadPool.MaxThreads/MinThreads。您在这里遭受了很多滥用。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2010-09-27
    • 1970-01-01
    • 2012-11-23
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多