为了记录ASP.NET web应用程序的日志,我将一些状态信息保存在静态类中。这些字段被标记为[ThreadStatic],因此每个线程都有自己的字段副本。日志记录方法从HttpApplication事件方法中调用:
现在我可以看到,在某些情况下,页面请求是在不同的线程中处理的。BeginRequest事件运行在线程18上,而下面的事件运行在线程4上。当然,我的线程静态数据是不可用的,并且会发生错误。
大多数情况下,这种方法工作得很好,每个请求都是在一个线程中处理的。但是,当我请求一个加载大约5秒的页面时,在1-2秒之后单击另一个链接,两个请求都并行运行。第一个线程在线程24上完成(在线程24上也已启动),而另一个线程在线程18上启动,但是在第一个请求完成后,第二个线程继续在线程4上运行。
尝试与3个重叠的长请求,这是一个纯粹的混乱。我甚至可以看到从同一个线程开始的两个请求,而它们随后在不同的线程上继续进行。在请求和线程之间似乎没有任何关系。
请求怎么会改变线程呢?如果它决定转到另一个线程,那么它就失去了所有的状态。我能找到的每一个描述都说这一切都发生在一个线程中。
ASP.NET 4.0 on IIS7,Windows 2008 R2,x64。
Alternative:,如果我不能依赖从一开始到最后仅在一个线程中处理的请求,那么存储每个请求的少量数据(目前是一个整数和一个类)的最佳位置是什么?而且最好也可以不引用System.Web (我的代码也针对客户端配置文件)。我知道HttpContext.Current.Items[key],但是它在远程处理程序集中的某个地方查找,并且涉及一个字典,它看起来比线程静态字段慢得多。
发布于 2014-06-06 14:27:23
ASP.NET是线程敏捷,一个请求可以在多个线程上处理(但不能同时处理多个线程)。因此,您实际上不能在ThreadStatics中使用ASP.NET,但是,您可以安全地使用HttpContext.Items字典来存储需要限定为单个请求的内容。
为了允许您的代码在ASP.NET应用程序的上下文之外工作,您可以创建一个交换HttpContext / CallContext的包装器,这取决于代码所在的环境。下面是这样一个包装器的示例。
https://stackoverflow.com/questions/24083360
复制相似问题