可以调用任务吗?如果知道任务已完成,则返回异步方法

本文关键字:任务 已完成 返回 异步方法 如果 调用 | 更新日期: 2023-09-27 18:14:10

我理解在async方法中调用task.Result可能导致死锁。不过,我对这个问题有不同的看法……

我发现自己经常这样做。我有几个任务返回相同类型的结果,所以我可以同时等待它们。但是,我想单独处理结果:

Task<int> t1 = m1Async();
Task<int> t2 = m2Async();
await Task.WhenAll(t1, t2);

是否可以在这里调用Result,因为我知道任务现在已经完成了?

int result1 = t1.Result;
int result2 = t2.Result;

或者,我应该使用await仍然…它看起来是多余的,可以有点难看,这取决于我需要如何处理结果:

int result1 = await t1;
int result2 = await t2;

更新:有人把我的问题标记为这个问题的副本:等待多个具有不同结果的任务。这个问题是不同的,这就是为什么我没有在我的搜索中找到它,尽管其中一个详细的答案也回答了我的问题。

可以调用任务吗?如果知道任务已完成,则返回异步方法

在您已经完成await之后使用t1.Result本身没有什么错误或不好的,但您可能会为将来的问题打开自己。如果有人在方法开始时更改了代码,使您无法再确定任务已成功完成,该怎么办?如果他们看不到你的代码,那该怎么办?

在我看来,使用第一个await的返回值可能会更好。

Task<int> t1 = m1Async();
Task<int> t2 = m2Async();
var results = await Task.WhenAll(t1, t2);
int result1 = results[0];
int result2 = results[1];

这样,如果有人弄乱了第一个await,就有一个自然的联系让他们知道你以后的代码依赖于它的结果。

您可能还需要考虑Task.WhenAll()在这里是否真的给了您任何价值。除非您希望区分一个任务失败和两个任务都失败,否则单独等待两个任务可能会很简单。

Task<int> t1 = m1Async();
Task<int> t2 = m2Async();
int result1 = await t1;
int result2 = await t2;

文档说Task.Result 等价于调用Wait方法

Wait被调用时

"任务是什么?"等待做什么?"

…如果Task运行到完成,Wait将成功返回。

(https://blogs.msdn.microsoft.com/pfxteam/2009/10/15/task-wait-and-inlining/)

所以您可以假设当您调用Task.Result时,它将成功返回,不会导致您提到的死锁。