".GetAwaiter().GetResult();"是否适用于一般使用?"

43

我在几个地方阅读到.GetAwaiter().GetResult();可能会导致死锁,因此我们应该使用async/await。但是我看到很多代码示例中仍然使用它。我可以使用它吗?在哪些情况下它可能会死锁?是否有其他可用的替代方法,例如Task.Wait

2个回答

72

正如我在我的博客上描述的那样,GetAwaiter().GetResult() 在单线程上下文中使用时可能会发生死锁问题。这在调用UI线程或ASP.NET(在Core之前的ASP.NET)上最常见。

Wait 也存在同样的问题。适当的解决方法是使用await并使调用代码异步化。

请注意,控制台应用程序中的Main方法是一个例外;在那里使用它是完全合适的。许多代码示例都是这样使用它的。


3
控制台应用程序中的主要方法是此规则的一个例外;在那里使用它是完全恰当的。许多代码示例都以这种方式使用它。这里有一个很好的观点。谢谢! - Teoman shipahi
@stephenCleary,关于主方法的评论是否适用于从ThreadPool.QueueUserWorkItem启动的线程内触发的方法? - Martin
@StephenCleary最佳答案是“原因”,我们为每个“事物”启动一个线程,并共享一些在Web解决方案中使用的Async代码...如果可能的话,我宁愿不将代码重新创建为Sync... - Martin
1
@Martin:我猜你的意思是你正在使用线程本地状态或其他需要专用线程的机制,并且你不想使代码异步。在这种情况下,当然可以使用GetAwaiter().GetResult()。我假设你的专用线程是无上下文的,所以它不应该出现死锁。 - Stephen Cleary
2
@Steven.Xi:一般情况下不行,但在特定场景下是可以实现的。请参考https://msdn.microsoft.com/en-us/magazine/mt238404.aspx。 - Stephen Cleary
显示剩余6条评论

1
在考虑这些事情时,查看官方文档会很有帮助。在备注部分,您会发现以下内容:

此方法适用于编译器使用;请勿直接在代码中使用。

我认为这提供了一个相当强的指引。它基本上给了.Net的开发人员一个许可证,在未来更改它的工作方式。他们可能永远不会这样做,但我自己不会感到自信。至于您应该使用什么其他内容,这取决于上下文,但async/await是最有可能的替代方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接