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

Car*_*ary 7 c# async-await

据我所知,在调用task.Result中的async方法可能会导致死锁.我对这个问题有不同的看法,但......

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

Task<int> t1 = m1Async();
Task<int> t2 = m2Async();
await Task.WhenAll(t1, t2);
Run Code Online (Sandbox Code Playgroud)

可以打电话Result到这里,因为我知道任务现在已经完成了吗?

int result1 = t1.Result;
int result2 = t2.Result;
Run Code Online (Sandbox Code Playgroud)

或者,我应该使用await静止...它似乎是多余的,可能有点丑陋取决于我需要如何处理结果:

int result1 = await t1;
int result2 = await t2;
Run Code Online (Sandbox Code Playgroud)

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

Str*_*ior 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];
Run Code Online (Sandbox Code Playgroud)

这样一来,如果有人与第一个混淆await,那么他们可以自然地联系,以便知道您的代码以后依赖于其结果.

您可能还想考虑是否Task.WhenAll()真的在这里给你任何价值.除非你希望告诉一个任务失败和失败之间的区别,否则单独等待任务可能很简单.

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

int result1 = await t1;
int result2 = await t2;
Run Code Online (Sandbox Code Playgroud)

  • @Cary:如果您在调用另一个之前等待第一个调用,那么您只是序列化调用.如果在"等待"来自`m1Async()`的结果之前调用`m2Async()`,那么第二次调用将在执行超出范围之前进行. (2认同)