0

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

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

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

这段代码可能需要改进,因为tasksToRunInCurrentBatch可以有超过 10k 个任务,我想最小化直到最后一个任务执行的总时间。

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

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

所以我从阅读几篇文章开始 - 如何:使用线程池使用线程

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

4

1 回答 1

1

看看这篇关于线程的详尽文章。在并发集合producer/consumer部分下,您可以找到执行任务的队列示例。

作为一般考虑,您不应该创建 10k个Task对象和Run()所有对象。相反,创建n 个 Task实例来执行您想要执行的 10k 个方法。

编辑

如果你想用来ThreadPool执行你想要的方法,你必须考虑以下几点:

  • 如果您的其中一个Actions 抛出异常怎么办?ThreadPool不会将异常编组到调用线程,因此您无法在调用线程上捕获它,它会使您的应用程序停机。
  • 你怎么知道所有Actions都完成了?ThreadPool不提供执行此操作的方法 - 它以非常接近于射击并忘记策略的方式执行操作。

另一方面Task Parallel Library,它建立在上面ThreadPool提供了优雅的方式来处理上述问题。上面链接中的PCQueue示例(并发集合)向您展示了如何处理您正在调用的 s 引发的异常,并提供了一种在所有操作完成后Action继续您的应用程序流程的方法。

你可以PCQueue这样使用:

var queue = new PCQueue(Environment.ProcessorCount);
var tasks = tasksToRunInCurrentBatch.Select(t=>queue.Enqueue(t.Value)).ToArray();
Task.WaitAll(tasks);
于 2013-10-01T07:01:12.730 回答