0

我有这样的代码:

var myTask = requiredTask.ContinueWith(_=>
{
    var otherTasks = from item in otherObjects select item.DoSomethingAsync();
    Task.WaitAll(otherTasks);
    // do my real work
});

我的理解是,当(IO 绑定)子任务完成时,对 WaitAll 的调用将阻塞并保留线程池中的一个线程。我的问题是:

  1. 我关于绑定线程池线程的假设是否正确?

  2. 如果是这样,避免这样做的最佳方法是什么?

请注意,这是针对需要支持 .NET4/Windows XP 的库,因此await不能选择使用。

4

1 回答 1

3

如果您包含Microsoft.Bcl.Async 程序集并使用兼容的 IDE (VS2012+) 构建,则可以将async/await与 .NET 4 一起使用。然后您可以await Task.WhenAll,例如

var myTask = await requiredTask;
var otherTasks = from item in otherObjects select item.DoSomethingAsync();
await Task.WhenAll(otherTasks);
// do my real work

由于Task.WhenAll是在 .NET 4.5 中添加的,而不是在 Microsoft.Bcl.Async 程序集中添加的,因此这就是在 .NET 4 中的操作方式:

var myTask = await requiredTask;
var otherTasks = (from item in otherObjects select item.DoSomethingAsync()).ToList();
foreach (var otherTask in otherTasks)
    await otherTask;

我还加入了一个ToList(),这样如果您otherTasks稍后使用(例如,获取结果),表达式将不会被重新评估。

于 2013-10-22T22:15:18.263 回答