Asp.net SynchronizationContext为异步继续锁定HttpApplication?

Asp.net SynchronizationContext为异步继续锁定HttpApplication?,asp.net,asp.net-mvc,multithreading,asynchronous,async-await,Asp.net,Asp.net Mvc,Multithreading,Asynchronous,Async Await,他说: AspNetSynchronizationContext是最奇怪的实现。它将Post视为同步而非异步,并且使用锁一次执行一个委托 类似地,该评论中的链接建议: 从概念上讲,AspNetSynchronizationContext的上下文是复杂的。在异步页面的生存期内,上下文仅从ASP.NET线程池中的一个线程开始。异步请求启动后,上下文不包括任何线程。异步请求完成后,执行其完成例程的线程池线程进入上下文。这些线程可能与启动请求的线程相同,但更有可能是在操作完成时空闲的线程 如果同一应用程

他说:

AspNetSynchronizationContext
是最奇怪的实现。它将
Post
视为同步而非异步,并且使用锁一次执行一个委托

类似地,该评论中的链接建议:

从概念上讲,AspNetSynchronizationContext的上下文是复杂的。在异步页面的生存期内,上下文仅从ASP.NET线程池中的一个线程开始。异步请求启动后,上下文不包括任何线程。异步请求完成后,执行其完成例程的线程池线程进入上下文。这些线程可能与启动请求的线程相同,但更有可能是在操作完成时空闲的线程

如果同一应用程序的多个操作同时完成,AspNetSynchronizationContext将确保它们一次执行一个操作。它们可以在任何线程上执行,但该线程将具有原始页面的标识和区域性

在reflector中挖掘似乎验证了这一点,因为它在调用任何回调时锁定了
HttpApplication

锁定应用程序对象看起来很可怕。因此,我的第一个问题是:这是否意味着今天,整个应用程序的所有异步完成一次执行一个,甚至是来自具有不同HttpContext的不同线程上的不同请求的异步完成?对于所有100%使用异步页面(或MVC中的异步控制器)的应用程序来说,这不是一个巨大的瓶颈吗?若否,原因为何?我错过了什么

另外,在.NET 4.5中,似乎有一个新的
AspNetSynchronizationContext
,旧的被重命名为
legacyapsnetsynchronizationcontext
,仅在未设置新的应用程序设置
UseTaskFriendlySynchronizationContext
时使用。那么问题2:新的实现是否改变了这种行为?否则,我想,如果使用新的async/await支持通过同步上下文封送完成,这种瓶颈将被更频繁地注意到


答案(链接自SO answer)表明这里发生了一些根本性的变化,但我想明确这是什么以及哪些行为得到了改进,因为我们有一个.NET 4 MVC 3应用程序,它几乎是100%异步操作方法,用于进行web服务调用。

让我回答您的第一个问题。假设您没有考虑单独的ASP.NET请求是由不同的HTTpApple对象处理的。HttpApplication对象存储在池中。请求页面后,将从池中检索应用程序对象,并在请求完成之前一直属于该请求。那么,我对你的问题的回答是:

整个应用程序的所有异步完成一次执行一个,即使是来自具有单独HttpContext的单独线程上的单独请求的异步完成

是:不,他们没有

单独的请求由单独的HttpApplication对象处理,锁定的HttpApplication将只影响单个请求。
同步上下文是帮助开发人员同步访问共享(在请求范围内)资源的强大工具。这就是为什么所有回调都是在锁定状态下执行的。同步上下文是基于事件的同步模式的核心。

我怀疑现有的行为被认为“足够好”。请记住,异步操作本身是独立的;只有它们的完成例程(和延续)是同步的。而且,异步页面在4.5之前是硬的;目前大多数ASP.NET应用程序都是同步的。我还没有机会查看新的ASP.NET synccontext。事实上,上周末刚刚安装了VS2012RC,获得了4.5版本!但如果没有其他人回答,我最终会在这里回答。请回答。你可能是这个话题上最权威的消息来源之一。讽刺的是,我今天早上在上班的路上边思考边意识到。您关于每个请求单独使用HttpApplication的回答绝对正确。谢谢你的洞察力。