Asp.net SynchronizationContext锁定HttpApplication以实现异步延续?

Jer*_*erg 13 asp.net asp.net-mvc multithreading asynchronous async-await

这个评论斯蒂芬·克利里这样说:

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

同样,他在同步上下文中写的文章与该评论中的链接表明:

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

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

挖掘反射器似乎验证了这一点,因为它HttpApplication在调用任何回调时需要锁定.

锁定app对象看起来像是可怕的东西.所以我的第一个问题:这是否意味着今天,整个应用程序的所有异步完成都会一次执行一个,即使是源自具有单独HttpContexts的单独线程上的单独请求的那些?对于任何100%使用异步页面(或MVC中的异步控制器)的应用程序来说,这不是一个巨大的瓶颈吗?如果没有,为什么不呢?我错过了什么?

此外,在.NET 4.5中,它看起来像是一个新的AspNetSynchronizationContext,旧的重命名LegacyAspNetSynchronizationContext,仅在UseTaskFriendlySynchronizationContext未设置新的应用程序设置时使用.问题2:新实现是否会改变这种行为?否则,我想通过同步上下文新的async/await支持编组完成,这种瓶颈会更频繁地被注意到.

这个论坛帖子的答案(从SO答案链接到这里)表明这里有一些根本改变的东西,但我想明确这是什么以及改进了什么行为,因为我们有一个.NET 4 MVC 3应用程序100%异步操作方法进行Web服务调用.

Ram*_*ich 11

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

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

是:不,他们没有

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