我需要使用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;
答案 0 :(得分:2)
假设要完成所有三个作业,并且它们都不依赖另一个,则在启动它们之后分别分别使用, since you want to stack your
和/或Task.WhenAll()
。您不必同时使用两者。
await
异步方法总是开始同步运行。因此,当您调用var task1 = Task1();
var task2 = Task2();
var task3 = Task3();
时,它将一直运行到对不完整的Task1()
起作用的第一个await
为止。那将是它开始等待您提出的任何I / O请求的时间。此时,Task
返回不完整的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()
之前 Task.WhenAll()
,那么在开始使用await task1
的结果之前,您将等待所有三个操作完成。如果您可以在其他任务完成之前使用task1
的结果,则无需使用task1
。
此:
Task.WhenAll()
将阻塞当前线程,直到var result1 = task1.Result;
var result2 = task2.Result;
var result3 = task3.Result;
完成为止。如果任务需要在当前上下文中恢复,则可能会陷入僵局。有关原因的说明,请参见此处:Don't Block on Async Code