根据已知的时间表,我需要为给定的任务列表调用Run
方法。
目前我只使用主线程的同步调用。
foreach (var task in tasksToRunInCurrentBatch)
{
Run(task.Key, task.Value);
}
此代码可能需要改进,因为tasksToRunInCurrentBatch
可以超过10k的任务,
我希望最小化上次执行任务之前的总时间。
Run
只执行任务的Action
,这应该很简单,但是用外部代码编写,我对它没有任何影响,它取决于在任务上。
我正在考虑使用线程池作为解决方案。
所以我开始阅读一些文章 - How to: Use a Thread Pool, Using Threading
这些文章解释了一切看起来都太好的基础知识。 在当前上下文中使用线程池时有哪些例外情况?
答案 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);