嵌套的Task.WhenAll有任何限制吗



让我们想象一些抽象代码

private void Main()
{
var workTask1 = DoWork1();
var workTask2 = DoWork2();
var workTask3 = DoWork3();
await Task.WhenAll(workTask1, workTask2, workTask3);
AnalyzeWork(workTask1.Result, workTask2.Result, workTask3.Result);
}
private async Task<object> DoWork1()
{
var someOperationTask1 = someOperation1();
var someOperationTask2 = someOperation2();
await Task.WhenAll(someOperationTask1, someOperationTask2);
return new object
{
SomeOperationResult1 = someOperationTask1.Result,
SomeOperationResult2 = someOperationTask2.Result,
};
}
private async Task<object> DoWork2()
{
var someOperationTask3 = someOperation3();
var someOperationTask4 = someOperation4();
await Task.WhenAll(someOperationTask3, someOperationTask4);
return new object
{
SomeOperationResult3 = someOperationTask3.Result,
SomeOperationResult4 = someOperationTask4.Result,
};
}
private async Task<object> DoWork3()
{
var someOperationTask5 = someOperation5();
var someOperationTask6 = someOperation6();
await Task.WhenAll(someOperationTask5, someOperationTask6);
return new object
{
SomeOperationResult5 = someOperationTask5.Result,
SomeOperationResult6 = someOperationTask6.Result,
};
}

其中3个方法并行运行,每个方法由2个并行操作组成。并将3种方法的结果传递给某个方法。

我的问题是有什么限制吗?有嵌套的Task.WhenAll可以吗?嵌套的Task.WhenAll和一级Task.WenAll操作有什么区别?

唯一的限制是系统的可用内存。Task.WhenAll方法为每个未完成的任务附加一个延续,并且在该任务完成时分离该延续。continuation是一个类似于Task的轻量级对象。它与调用Task.ContinueWith方法时得到的结果非常相似。每个延续的权重或多或少约为100个字节。它不太可能对你的程序产生任何明显的影响,除非你需要一次Task.WhenAll数千万(或更多)的任务。

如果你想直观地演示一下这个方法的内部情况,下面是它的实现草图:

// For demonstration purposes only. This code is full of bugs.
static Task WhenAll(params Task[] tasks)
{
var tcs = new TaskCompletionSource();
int completedCount = 0;
foreach (var task in tasks)
{
task.ContinueWith(t =>
{
completedCount++;
if (completedCount == tasks.Length) tcs.SetResult();
});
}
return tcs.Task;
}

相关内容

最新更新