我目前正在阅读Stephen Cleary撰写的“ C#Cookbook中的并发性 ”,并且注意到以下技术:
var completedTask = await Task.WhenAny(downloadTask, timeoutTask); if (completedTask == timeoutTask) return null; return await downloadTask;
downloadTask是对的调用httpclient.GetStringAsync,timeoutTask正在执行Task.Delay。
downloadTask
httpclient.GetStringAsync
timeoutTask
Task.Delay
如果它没有超时,则downloadTask已经完成。downloadTask.Result考虑到任务已经完成,为什么需要第二次等待而不是返回?
downloadTask.Result
这里已经有一些不错的答案/评论,但是只是为了…
有两个原因为什么我喜欢await过Result(或Wait)。首先是错误处理不同;await不会将异常包装在中AggregateException。理想情况下,异步代码根本不需要处理AggregateException,除非它特别 想要 处理。
await
Result
Wait
AggregateException
第二个原因有些微妙。正如我在博客(和书中)中所描述的那样,Result/ Wait可能导致死锁,并且在async方法中使用时可能会导致更细微的死锁。因此,当我阅读代码并看到Result或时Wait,这是立即警告标志。的Result/ Wait如果你是唯一正确的 绝对肯定 的任务已经完成。这不仅一目了然(在现实世界的代码中),而且对代码的更改也更加脆弱。
async
这并不是说Result/ Wait应该 永远不会 被使用。我在自己的代码中遵循以下准则:
请注意,(1)到目前为止是最常见的情况,因此,我倾向于在await所有地方使用并将其他情况视为一般规则的例外。