Stephen Cleary的评论是这样说的:
AspNetSynchronizationContext
是最奇怪的实现。它视为Post
同步而不是异步,并使用锁一次执行一个委托。
同样,他写的关于同步上下文并在该评论中链接到的文章表明:
从概念上讲,AspNetSynchronizationContext 的上下文是复杂的。在异步页面的生命周期中,上下文仅从 ASP.NET 线程池中的一个线程开始。异步请求启动后,上下文不包含任何线程。当异步请求完成时,执行其完成例程的线程池线程进入上下文。这些可能是发起请求的相同线程,但更有可能是在操作完成时碰巧空闲的任何线程。
如果同一应用程序一次完成多个操作,AspNetSynchronizationContext 将确保它们一次执行一个。它们可以在任何线程上执行,但该线程将具有原始页面的身份和文化。
挖掘反射器似乎可以验证这一点,因为它HttpApplication
在调用任何回调时会锁定。
锁定应用程序对象似乎很可怕。所以我的第一个问题是:这是否意味着今天,整个应用程序的所有异步完成都一次执行一个,即使是源自具有单独 HttpContext 的单独线程上的单独请求的那些?对于任何 100% 使用异步页面(或 MVC 中的异步控制器)的应用程序来说,这不是一个巨大的瓶颈吗?如果不是,为什么不呢?我错过了什么?
此外,在 .NET 4.5 中,似乎有一个新AspNetSynchronizationContext
的,旧的被重命名LegacyAspNetSynchronizationContext
,并且仅在UseTaskFriendlySynchronizationContext
未设置新的应用程序设置时使用。所以问题 #2:新的实现会改变这种行为吗?否则,我想随着新的 async/await 支持通过同步上下文封送完成,这种瓶颈会更频繁地被注意到。
这个论坛帖子的答案(从这里的 SO 答案链接)表明这里发生了根本性的变化,但我想弄清楚那是什么以及哪些行为得到了改进,因为我们有一个 .NET 4 MVC 3 应用程序,它几乎100% 异步操作方法进行 Web 服务调用。