我想收集/运行任务,然后对它们进行Task.WhenAll
。
var tasks = new List<Task>();
foreach (var thing in things) {
tasks.Add(Task.Run(async () => {
// async stuff using thing
}));
}
var stuffs = await Task.WhenAll(tasks);
在这里使用Task.Run
是否正确<或者
tasks.Add(new Func<Task>(async () => {async stuff})());
还是别的什么呢?
答案 0 :(得分:7)
这通常取决于您的异步工作的性质。如果您执行以下操作:
async () => {
// some heavy CPU work here
// then some IO
}
使用Task.Run
会更好,因为否则&#34;繁重的CPU工作&#34;将在您当前的线程上运行,您将获得很少的并行化。
async () => {
// some async IO, like database call or web request
// some processing
// some more async IO
}
然后你不需要Task.Run
。然后你可以使用你的第二种方法:
Func<Task> t = async () => {
// some stuff
};
tasks.Add(t());
如果你在UI线程上(在WPF \ WinForms中)这样做 - 确保在异步委托中使用ConfigureAwait(false)
以防止将控制返回到UI线程。
答案 1 :(得分:1)
除了Evk's response之外,了解并行性的潜在差异以及是否需要考虑线程安全性也很重要。
如果满足以下所有条件,则“ func”不需要是线程安全的:
new Func
方法ConfigureAwait(false)
SynchronizationContext
是一个同步上下文,这意味着它保证一次只能有一个线程可以执行代码(与旧式ASP.NET中一样)否则,您需要考虑“ func”的线程安全性。