关于MVC中异步/等待的矛盾建议

时间:2018-02-15 14:16:35

标签: c# asp.net-mvc async-await

我一直在开发一些将由MVC操作方法使用的库代码,所以我一直在阅读很多关于这个主题的Steven Cleary的博客。

我参加了他的“Don't Block on Async Code”博客文章,但我对一些似乎相互矛盾的部分感到困惑。

在“防止僵局”下,他说:

  

有两个最佳实践(我的介绍帖中都有)   避免这种情况:

     
      
  1. 在“库”异步方法中,无论何处使用ConfigureAwait(false)   可能。

  2.   
  3. 不要阻止任务;一直使用async。

  4.   

然后:

  

使用ConfigureAwait(false)来避免死锁是一件危险的事情   实践。您必须为每个await使用ConfigureAwait(false)   在阻塞代码调用的所有方法的传递闭包中,   包括所有第三方和第二方代码。运用   ConfigureAwait(false)以避免死锁充其量只是一个hack)。

鉴于这两个陈述,有人说ConfigureAwait(false)是库代码的最佳实践,并且说它充其量只是一个危险的黑客,编写库代码的实际正确方法是什么?在MVC中使用死锁?

我已经阅读了其他问题和答案,因为可能被认为是重复的,但它们似乎都没有解决其中一位专家在async / await上提供的矛盾信息。 / p>

1 个答案:

答案 0 :(得分:3)

除非您将这些信息脱离背景,否则这些信息不会直接相互矛盾:

前者是编写库代码的一般建议;做这些事情是个好主意,以确保你的图书馆表现良好,无论它被调用的同步环境如何。

后者明确地提到如何使用ConfigureAwait(false)作为避免已知死锁场景的手段。它说,

  

我想在这里阻止,但这样做通常会导致死锁,所以我将工作推送到另一个线程(来自线程池)并希望一切正常。

如果遵循早先的建议不阻止任务(一直使用异步),那么这种死锁情况就不会发生。

死锁场景仅在特定同步上下文中运行代码时相关,该特定同步上下文在启动任务的线程上安排继续执行,例如ASP.NET使用的(在一个线程上处理请求)或者Windows桌面应用程序使用(所有UI事件的单个线程)。

在这些上下文中阻塞任务会导致单个线程被阻塞,因此线程永远不会自由运行continuation和方法死锁。

相关问题