可以调用任务吗?如果知道任务已完成,则返回异步方法
本文关键字:任务 已完成 返回 异步方法 如果 调用 | 更新日期: 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
被调用时
(https://blogs.msdn.microsoft.com/pfxteam/2009/10/15/task-wait-and-inlining/)"任务是什么?"等待做什么?"
…如果Task运行到完成,Wait将成功返回。
所以您可以假设当您调用Task.Result
时,它将成功返回,不会导致您提到的死锁。