是 .GetAwaiter().GetResult();一般使用安全吗?

Posted

技术标签:

【中文标题】是 .GetAwaiter().GetResult();一般使用安全吗?【英文标题】:Is .GetAwaiter().GetResult(); safe for general use? 【发布时间】:2016-12-24 17:22:18 【问题描述】:

我在一些地方读到.GetAwaiter().GetResult(); 可能导致死锁,我们应该使用async/await 代替。但是我看到许多使用它的代码示例。可以使用吗?哪些情况会导致死锁?还有什么我应该使用的,比如Task.Wait

【问题讨论】:

【参考方案1】:

正如我在博客中所描述的,GetAwaiter().GetResult() can deadlock when it's used in a one-thread-at-a-time context。这在 UI 线程或 ASP.NET 上下文(对于 pre-Core ASP.NET)中调用时最常见。

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

请注意,控制台应用程序中的 Main 方法是此规则的一个例外;在那里使用非常合适。许多代码示例都以这种方式使用它。

【讨论】:

我认为 WebApi 服务也是如此,对吗? @Cyan:是的,任何类型的 ASP.NET 请求上下文。 Pre-Core,即;请求上下文已在 ASP.NET Core 中删除。 "控制台应用程序中的 Main 方法是此规则的一个例外;它非常适合在那里使用。许多代码示例都以这种方式使用它。"这里有一个完美的观点。谢谢! @Martin:我假设您的意思是您正在使用线程本地状态或其他需要专用线程的机制,并且您不想使代码 异步。在这种情况下,当然,只需使用GetAwaiter().GetResult()。我假设你的专用线程是无上下文的,所以它不应该死锁。 @Steven.Xi:一般情况下不会。在特定场景下,是可以做到的。见msdn.microsoft.com/en-us/magazine/mt238404.aspx

以上是关于是 .GetAwaiter().GetResult();一般使用安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

C#同步调用异步方法

WorkSample.Quartz

在构造函数中执行任务 [重复]

async await 同步方法调用异步方法死锁

在 mongo 中插入 doc 时 E11000 重复键错误收集

FromBluetoothAddressAsync IAsyncOperation 不包含“GetAwaiter”错误的定义