如果您知道任务已完成,可以在异步方法中调用task.Result吗?

时间:2016-10-21 22:44:32

标签: c# async-await

我了解在task.Result方法中调用async会导致死锁。我对这个问题有不同的看法,但是......

我发现自己做了很多这种模式。我有几个返回相同类型结果的任务,所以我可以一次等待它们。我想分别处理结果:

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;

更新:有人将我的问题标记为此问题的副本:Awaiting multiple Tasks with different results。 问题是不同的,这就是为什么我没有在我的搜索中找到它,虽然其中一个详细的答案确实可以回答。

2 个答案:

答案 0 :(得分:5)

在您完成t1.Result之后使用await并没有任何内在错误或错误,但您可能会对未来的问题敞开心扉。如果有人在您的方法开头更改代码,那么您不能再肯定任务已成功完成该怎么办?如果他们没有看到你的代码进一步向下做出这个假设怎么办?

在我看来,使用第一个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;

答案 1 :(得分:1)

该文档说Task.Result it is equivalent to calling the Wait method

调用Wait

  

“Task.Wait做什么?”

     

...如果任务运行完成,Wait将成功返回。

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

因此,您可以假设当您致电Task.Result时,它会成功返回,但不会导致您提到的死锁。