有关MVC中异步/等待的矛盾建议 [英] Contradictory advice regarding async / await in MVC

查看:64
本文介绍了有关MVC中异步/等待的矛盾建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发一些库代码,这些代码将由MVC动作方法使用,因此,我已经阅读了很多史蒂文·克雷里(Steven Cleary)关于该主题的博客.

I've been developing some library code that will be consumed by MVC action methods, so I've been reading a lot of Steven Cleary's blogs about the subject.

我遇到了他的"不要阻止异步代码"博客文章,但对某些似乎矛盾的部分感到困惑.

I ran in to his "Don't Block on Async Code" blog post, but am confused about some parts that seem contradictory.

在防止僵局"下,他说:

Under "Preventing the Deadlock" he states:

有两种最佳做法(在我的介绍性文章中都有介绍)避免这种情况:

There are two best practices (both covered in my intro post) that avoid this situation:

  1. 在库"异步方法中,无论何时何地都可以使用ConfigureAwait(false)可能的.

  1. In your "library" async methods, use ConfigureAwait(false) wherever possible.

不要阻止任务";一直使用异步.

Don’t block on Tasks; use async all the way down.

然后再来

使用ConfigureAwait(false)避免死锁是很危险的实践.您必须为每次等待使用ConfigureAwait(false)在阻塞代码调用的所有方法的传递性关闭中,包括所有第三方代码.使用避免死锁的ConfigureAwait(false)充其量只是一个hack).

Using ConfigureAwait(false) to avoid deadlocks is a dangerous practice. You would have to use ConfigureAwait(false) for every await in the transitive closure of all methods called by the blocking code, including all third- and second-party code. Using ConfigureAwait(false) to avoid deadlock is at best just a hack).

给出这2条语句,一条说 ConfigureAwait(false)是库代码的最佳实践,而另一条说这充其量是危险的hack,实际的正确写法是什么?在MVC中使用时不会死锁的库代码?

Given these 2 statements, one saying that ConfigureAwait(false) is a best practice for library code, and one that says it is at best a dangerous hack, what is the actual proper way to write library code that won't deadlock when used in MVC?

我已经阅读了其他问答,因此可能可能被认为是重复的,但它们似乎都没有解决一位异步/等待专家给出的矛盾信息./p>

I've read other question and answers on SO that might be considered duplicates of this, but none of them seem to address the contradictory information given by one of the experts on async / await.

推荐答案

除非您脱离上下文,否则这些信息并不直接矛盾:

The information isn't directly contradictory unless you take them out of context:

前者是编写库代码的一般建议;最好执行这些操作以确保您的库在调用同步上下文的情况下均表现良好.

The former is general advice to writing library code; it's a good idea to do these things to make sure your library behaves well regardless of the synchronization context it's called in.

后者明确指出了如何使用 ConfigureAwait(false)作为避免已知死锁情况的一种手段.就是说

The latter is explicitly calling out how using ConfigureAwait(false) as a means to avoid a known deadlock scenario is a hack. It's saying,

我想在这里阻塞,但是这样做通常会导致死锁,所以我将把工作推到另一个线程(从线程池中),希望一切顺利.

I want to block here, but doing so would normally cause a deadlock, so I'll push the work to another thread (from the thread-pool) and hope everything works out okay.

如果按照先前的建议不阻塞任务(一直使用异步),那么就不会发生这种死锁情况.

If following the earlier advice to not block on tasks (use async all the way down), then this deadlock scenario won't happen.

仅当在特定的同步上下文中运行代码以安排继续在启动任务的线程上执行(例如,ASP.NET使用的线程(一个请求在一个线程上处理))时,死锁方案才有意义.由Windows桌面应用程序使用(所有UI事件使用一个线程).

The deadlock scenario is only relevant when running code within specific synchronization contexts which schedule continuations to execute on the thread which started the task, such as the one used by ASP.NET (a request is processed on one thread) or the one used by Windows desktop applications (a single thread for all UI events).

在这些情况下阻塞任务会导致单个线程被阻塞,因此线程永远不会自由地运行延续和方法死锁.

Blocking on the task in these contexts causes the single thread to block, so the thread is never free to run the continuation and the method deadlocks.

这篇关于有关MVC中异步/等待的矛盾建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆