HttpApplication events changing threads
为了记录ASP.NET Web应用程序的日志,我将一些状态信息保存在静态类中。这些字段标记为
- 应用程序开始请求(请求开始,初始化状态)
- 应用程序请求状态(会话和用户已知)
- 应用程序结束请求(请求结束,清除)
我现在可以观察到,在某些情况下,页面请求是在不同的线程中处理的。BeginRequest事件在线程18上运行,而以下事件在线程4上运行。当然,我的线程静态数据是不可用的,并且会发生错误。
大多数情况下,这种方法工作得很好,每个请求都只在一个线程中处理。但是,当我请求一个加载大约5秒的页面,并在1-2秒后单击另一个链接时,两个请求并行运行。第一个在线程24上完成(其中它也启动了),5秒后,另一个在线程18上启动,但在第一个请求完成后,第二个继续在线程4上运行。
尝试3个重叠的长请求,这是一个纯粹的混乱。我甚至可以看到在同一线程上启动的两个请求,而它们稍后会分别在不同的线程上继续。请求和线程之间似乎没有任何关系。
请求是如何更改线程的?如果它决定转移到另一个线程,那么它将失去所有的状态。我能找到的每一个描述都说这一切都发生在一个线程中。
IIS 7、Windows Server 2008 R2、x64上的ASP.NET 4.0。
备选方案:如果我不能依赖于从开始到结束只在一个线程中处理的请求,那么存储少量快速访问的每个请求数据(当前是一个整数和一个类)的最佳位置是什么?而且最好在没有引用System.Web的情况下工作(我的代码也针对客户机配置文件)。我知道
ASP.NET是线程敏捷的,一个请求可以在多个线程上处理(但一次不能处理多个线程)。因此,您不能在ASP.NET中使用ThreadStatics。但是,您可以安全地使用httpContext.items字典来存储需要限定到单个请求范围的内容。
为了允许代码在ASP.NET应用程序上下文之外工作,可以创建一个交换httpContext/callContext的包装器,具体取决于代码所在的环境。下面是这样一个包装器的例子。