Task.WhenAll 是如何工作的
How Task.WhenAll works under the hood
Task.WhenAll
是如何工作的?它是否创建单独的线程,一旦所有任务都收到关于完成的回调就完成了。我有一个建议,它在后台创建新线程并将工作传递给每个任务的系统驱动程序并在最后等待它们,但不确定它是否正确?
不,Task.WhenAll
不创建线程。传递给 Task.WhenAll
的某些元素任务可能已经创建了线程(但最好不会)。 Task.WhenAll
本身只是在元素任务上调用 ContinueWith
,传递一段检查其他任务状态的代码。没有“等待”。
这里是如何实施 Task.WhenAll
的示例。 (不是微软代码)
Task MyWhenAll(IEnumerable<Task> tasks)
{
var a = tasks.ToArray();
var tcs = new TaskCompletionSource<bool>();
Array.ForEach(a, WatchTask);
return tcs.Task;
async void WatchTask(Task t)
{
try {
await t;
}
catch {}
if (a.All(element => element.IsCompleted)) {
if (a.Any(element => element.IsFaulted))
// omitted logic for adding each individual exception
// to the aggregate
tcs.TrySetException(new AggregateException());
else
tcs.TrySetResult(true);
}
}
}
Task.WhenAll
是如何工作的?它是否创建单独的线程,一旦所有任务都收到关于完成的回调就完成了。我有一个建议,它在后台创建新线程并将工作传递给每个任务的系统驱动程序并在最后等待它们,但不确定它是否正确?
不,Task.WhenAll
不创建线程。传递给 Task.WhenAll
的某些元素任务可能已经创建了线程(但最好不会)。 Task.WhenAll
本身只是在元素任务上调用 ContinueWith
,传递一段检查其他任务状态的代码。没有“等待”。
这里是如何实施 Task.WhenAll
的示例。 (不是微软代码)
Task MyWhenAll(IEnumerable<Task> tasks)
{
var a = tasks.ToArray();
var tcs = new TaskCompletionSource<bool>();
Array.ForEach(a, WatchTask);
return tcs.Task;
async void WatchTask(Task t)
{
try {
await t;
}
catch {}
if (a.All(element => element.IsCompleted)) {
if (a.Any(element => element.IsFaulted))
// omitted logic for adding each individual exception
// to the aggregate
tcs.TrySetException(new AggregateException());
else
tcs.TrySetResult(true);
}
}
}