使用线程池时的例外情况有哪些

时间:2013-10-01 06:48:11

标签: c# multithreading c#-4.0 visual-studio-2012

根据已知的时间表,我需要为给定的任务列表调用Run方法。

目前我只使用主线程的同步调用。

foreach (var task in tasksToRunInCurrentBatch)
{
    Run(task.Key, task.Value);
}

此代码可能需要改进,因为tasksToRunInCurrentBatch可以超过10k的任务, 我希望最小化上次执行任务之前的总时间。

Run只执行任务的Action ,这应该很简单,但是用外部代码编写,我对它没有任何影响,它取决于在任务上。

我正在考虑使用线程池作为解决方案。

所以我开始阅读一些文章 - How to: Use a Thread PoolUsing Threading

这些文章解释了一切看起来都太好的基础知识。 在当前上下文中使用线程池时有哪些例外情况?

1 个答案:

答案 0 :(得分:1)

看看this extensive article on threading。在Concurrent collections部分下,您可以找到执行任务的producer/consumer队列示例。

作为一般考虑因素,您不应创建10k Task个对象和Run()个对象。而是创建 n Task实例,这些实例将执行您要执行的10k方法。

修改

如果您想使用ThreadPool执行您想要的方法,则必须考虑以下因素:

  • 如果你的Action之一引发异常怎么办? ThreadPool不会将调用线程的异常编组,因此您无法在调用线程上捕获它,它会使您的应用程序失效。
  • 您如何知道所有 Action已完成? ThreadPool没有提供这样做的方法 - 它以非常接近 fire并忘记策略的方式执行操作。

另一方面Task Parallel Library建立在ThreadPool之上,提供了处理上述问题的优雅方法。上面链接中的PCQueue示例(Concurrent collections)向您展示了如何处理从您调用的Action引发的异常,并提供了在时继续应用程序流的方法所有动作都已完成。

您可以像这样使用PCQueue

var queue = new PCQueue(Environment.ProcessorCount);
var tasks = tasksToRunInCurrentBatch.Select(t=>queue.Enqueue(t.Value)).ToArray();
Task.WaitAll(tasks);