C# 如何捕获任务结果 Task.WhenAll? ".Result"或"await"



我需要使用 Task.WhenAll 并发运行 3 个或更多任务,一旦 Task.WhenAll 完成执行所有任务,我想捕获所有任务的结果。

如何获取使用 Task.WhenAll 执行的那些任务的结果?

我应该使用.Result还是await?为什么呢?

.Result会阻止吗?

这是代码示例:

var task1 = Task1();
var task2 = Task2();
var task3 = Task3();
await Task.WhenAll(task1, task2, task3);
// 1st approach:
var result1 = task1.Result;
var result2 = task2.Result;
var result3 = task3.Result;
// 2nd approach:
var result1 = await task1;
var result2 = await task2;
var result3 = await task3;

假设你想完成所有三个工作,并且它们都不依赖于另一个,那么在启动它们后分别使用Task.WhenAll()和/或await。您不一定需要同时使用两者。

var task1 = Task1();
var task2 = Task2();
var task3 = Task3();

异步方法始终同步开始运行。所以当你调用Task1()时,它将运行到作用于不完整Task的第一个await。这将是它开始等待您发出的任何 I/O 请求的时候。此时,Task1()返回一个不完整的Task,执行继续进行下一行:运行Task2()等。

这样可以充分利用资源,因为您利用等待响应的时间Task1()Task2()等中启动下一个请求。

如果使用await Task.WhenAll,则释放当前线程以执行其他工作。这三个任务很可能在完成等待(取决于一些事情(后在当前线程上恢复,一个接一个,无论它们各自的请求以什么顺序完成。一旦它们全部完成,执行将在await Task.WhenAll之后继续下一行。

这:

var result1 = await task1;
var result2 = await task2;
var result3 = await task3;

与执行Task.WhenAll()非常相似(因为您之前已经开始了任务(。但在这里,您正在捕获从每个返回的结果。如果您需要使用结果,那么您应该使用它。

如果您在await task1之前使用Task.WhenAll(),那么您将等待所有三个完成,然后再开始使用task1的结果。如果可以在其他任务完成之前使用task1的结果,则无需使用Task.WhenAll()

这:

var result1 = task1.Result;
var result2 = task2.Result;
var result3 = task3.Result;

将阻塞当前线程,直到task1完成。如果需要在当前情况下恢复任务,这很可能陷入僵局。请参阅此处了解原因:不要阻止异步代码

最新更新