HttpContext.Current如何处理IIS管道中的每个请求?

时间:2015-01-18 10:42:47

标签: c# asp.net pipeline httpcontext

如您所知,HttpContext.Current返回应用程序管道中的当前上下文 此属性也是static,因此逻辑上对该属性或其属性的任何更改都应该影响其他管道。

  

静态字段确切地标识一个存储位置。不管怎样   创建了一个类的许多实例,只有一个副本   静态字段。   More

IIS如何处理此问题以防止其他管道发生冲突,并且每个管道上的每个HttpContext.Current都是唯一的?

例如,对于已登录系统的两个用户,HttpContext.Current.User.Identity.Name会将发送请求的用户的用户名提供给服务器。

ASP.NET管道:
enter image description here

2 个答案:

答案 0 :(得分:7)

Current是属性,而不是字段,所以它实际上是一个静态方法。

这个方法可以为不同的线程返回不同的实例,而且确实如此。

如果您正在开发多线程Web应用程序,请记住一些事项。

  1. 请勿使用ThreadStaticAttribute。它适用于Windows和控制台应用程序,但它可能无法在Web应用程序中运行,因为如果您使用asyncawaitTask<T>,则可以由不同的线程处理单个请求。

  2. 使用HttpContext.Current.Items代替ThreadStaticAttribute。这些Items在每个HttpContext中都是“静态的”。

  3. 如果您在异步调用后需要HttpContext(区域设置,已记录用户和您自己的HttpContext.Items)的重要设置(如果您不使用{{},请使用SynchronizationContext {1}})。

  4. 你应该小心的原因是一个线程池。您的异步方法很可能开始在第一个线程中运行,在一秒钟内继续运行,在第三个线程中结束。由于每个线程都有自己的线程静态字段副本,因此您可以在方法的不同位置获得不可预测的不同字段值。 await允许您使用正确的区域设置值SynchronizationContext等返回初始线程。HttpContext.Items运算符可以帮助您,因此您不应该关心上下文,如果您正在使用await(感谢@StephenCleary进行更正)。

    现在为线程静态字段。当ASP.NET获取HTTP请求时,它会创建具有空await集合的HttpContext的新实例。同时,先前的HTTP请求已初始化HttpContext.Items个字段。因此f.e.基于线程静态字段的ThreadStatic类可能无法正常工作。它在Web应用程序的同步和异步方法中都很重要。

答案 1 :(得分:4)

答案在于线程本地存储,在.NET中使用ThreadStatic实现。环境上下文设计模式也与此相关。