异步HttpWebRequests和null HttpContext.Current.Response/Request对象

aep*_*eus 5 null asynchronous response httpwebrequest httpcontext

我有一个很大程度上依赖于Web服务的Web应用程序.服务的所有内容都是异步完成的,并使用AddOnPreRequestHandlerExecuteAsync.无论如何,我的大多数调用都运行得很好,但是有些调用从异步服务调用返回,在endprerequest中找到一个空的HttpContext.Current.Response/Request对象,当然我试图使用这个错误.两个对象(响应和请求在初始请求失败的调用时可用/非空,并且在其他调用的最终请求中工作).

任何人遇到类似的问题,或猜测可能是什么问题?

更新:似乎找到了一个解决方案,如果我在Init上创建一个HttpApplication的变量(HttpModule的这一切都发生在那里),可以从该变量访问HttpContext.

更新:在begin函数上传递HttpApplication或HttpContext.Current具有相同的问题.当作为异步调用的"状态"的一部分传递时,它们在end函数中最终为null,即使它们在begin函数中有效.

更新:我添加了一些日志记录,发现我正在进行的异步调用正确返回,结果存在,回调函数被正确调用.

Jus*_*ant 5

我怀疑我知道你遇到的问题.几乎可以肯定,答案是替换HttpWebRequestwith的使用WebClient,并使用*Async方法WebClient.

这里有很长的解释:有两种完全不同的异步编程模型:IAsyncResult异步模式基于事件的异步模式.IAsyncResult模式使用BeginXXXEndXXX方法,使用IAsyncResult实例,使用委托进行回调,并支持等待完成.基于事件的模式使用XXXAsync方法启动异步操作,使用XXXCompleted事件而不是回调来处理完成,并且(这对您的情况很重要)将特定于线程的上下文传输到每个回调事件处理程序.

换句话说,如果将回调代码放在XXXCompleted事件处理程序(如WebClient.DownloadStringCompleted)中,则将正确填充HttpContext.Current.

但是,如果使用BeginXXX方法(如HttpWebRequest.BeginGetResponse)和委托回调,则回调将在不保证附加正确ASP.NET上下文的线程的上下文中执行.

通常,.NET Framework库类使用一个异步模式或另一个.通常,较低级别的类(例如HttpWebRequest)将使用IAsyncResult模式,而较高级别的类(例如WebClient)将使用基于事件的模式.一些古怪的类(例如自动生成的.NET Remoting代理)将支持这两种模式,但这很少见.

因此,如果它很容易,我建议转移到WebClient和事件处理程序,而不是HttpWebRequest和回调委托.这应该可以解决您的问题.如果切换到WebClient太难了,评论和我可能会提出一些更加模糊的选择.


aep*_*eus 0

似乎找到了解决方案,如果我在 Init 上为 HttpApplication 创建一个变量(这一切都发生在 HttpModule 中),则可以从该变量访问 HttpContext。