在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
昨天碰见了一个怪事,同样的一个方法A(),在控制台程序中调用和在Asp.Net页面中调用,结果完全不一样。在控制台程序中运行正常,在Asp.Net下不能得到正确结果。
方法A()的执行过程如下:
A()调用第三方库的异步方法B(),在异步方法的回调方法C()之中,又调用了异步WebService Request。
Asynchronous operations are not allowed in this context. Page starting an asynchronous operation has to have the Async attribute set to true and an asynchronous operation can only be started on a page prior to PreRenderComplete event.
搜索 Google 发现,asp.net 对异步调用进行了限制,如要在 Page 中进行异步操作,需要设置Page的 Async = true; 然而,问题是在Page中触发的仅仅是方法A,A再调用方法B,B的回调则是由无名的苦工线程在幕后执行的,C的回调又是一个无名的苦工线程在幕后执行的,两个苦工线程,和Page线程根本不是一个线程,因此,在Page中设置Async=true能否影响到后台苦工线程值得怀疑。
public override void OperationStarted()
}
持有 AspNetSynchronizationContext 的是一个静态类 System.ComponentModel.AsyncOperationManager的静态属性SynchronizationContext。
.Net 程序中,WebService使用SoapHttpClientProtocol进行Soap Request,而SoapHttpClientProtocol是WebClient类的子类,在WebClient类的许多异步方法中,都调用了System.ComponentModel.AsyncOperationManage.SynchronizationContext.OperationStarted()方法. 如果碰上当前线程应用的是AspNetSynchronizationContext,而该AspNetSynchronizationContext又不允许异步操作,就出现了异常。
internal void Enter(bool setImpersonationContext)
原来SynchronizationContext在这里被偷梁换柱了。吃饱了撑的。
测试通过。
不过这样做副作用还不小,比如SynchronizationContext经常会被HttpApplication替换成AspNetSynchronizationContext,在这时进行异步操作就会出问题,再比如,使用System.Threading.SynchronizationContext而不是AspNetSynchronizationContext,会导致Asp.Net自身出现异常,昨天运行时就有一次HttpApplication抛了个异常。
System.Threading.SynchronizationContext context = System.ComponentModel.AsyncOperationManager.SynchronizationContext;
try }
测试通过。至今天,还没发现什么问题。 |
请发表评论