C# HttpContext.Current如何处理IIS管道中的每个请求?
如您所知,返回应用程序管道中的当前上下文。C# HttpContext.Current如何处理IIS管道中的每个请求?,c#,asp.net,pipeline,httpcontext,C#,Asp.net,Pipeline,Httpcontext,如您所知,返回应用程序管道中的当前上下文。 此外,该属性是静态的,因此从逻辑上讲,对该属性或其属性的任何更改都会影响其他管道 静态字段仅标识一个存储位置。无论如何 创建了一个类的多个实例,但该类只有一个副本 静电场。 IIS如何处理此问题以防止其他管道和每个HttpContext上的冲突。当前的在每个管道上都是唯一的 例如,对于已经登录到系统的两个用户,HttpContext.Current.User.Identity.Name提供向服务器发送请求的用户的用户名 ASP.NET管道: Curr
此外,该属性是静态的,因此从逻辑上讲,对该属性或其属性的任何更改都会影响其他管道 静态字段仅标识一个存储位置。无论如何 创建了一个类的多个实例,但该类只有一个副本 静电场。 IIS如何处理此问题以防止其他管道和每个
HttpContext上的冲突。当前的在每个管道上都是唯一的
例如,对于已经登录到系统的两个用户,HttpContext.Current.User.Identity.Name
提供向服务器发送请求的用户的用户名
ASP.NET管道:
Current
是属性,而不是字段,因此它实际上是一个静态方法
这个方法可以为不同的线程返回不同的实例,而且确实如此
如果您正在开发多线程web应用程序,请记住几件事
不要使用ThreadStaticAttribute
。它在Windows和控制台应用程序中工作,但在web应用程序中可能不工作,因为如果使用async
、wait
和Task
,单个请求可以由不同的线程处理
使用HttpContext.Current.Items
而不是ThreadStaticAttribute
。这些项在每个HttpContext
中都是“静态的”
如果在异步调用后需要对HttpContext
(区域设置、登录用户和您自己的HttpContext.Items
)进行重要设置(如果您未使用wait
),请使用此选项
您应该小心的原因是线程池。异步方法很可能在第一个线程中开始运行,在第二个线程中继续,在第三个线程中结束。由于每个线程都有自己的线程静态字段副本,因此可以在方法的不同位置获得不可预测的不同字段值SynchronizationContext
允许您使用区域设置的正确值返回初始线程,HttpContext.Items
等。await
操作符对您有效,因此如果您使用的是await
(感谢@StephenCleary的更正)
现在是线程静态字段。当ASP.NET收到HTTP请求时,它将使用空的HttpContext.Items
集合创建HttpContext
的新实例。同时,ThreadStatic
字段已经由以前的HTTP请求初始化。因此,基于线程静态字段的f.e.Singleton
类可能无法正常工作。它在web应用程序的同步和异步方法中都很重要。答案在于线程本地存储,用in.NET实现。环境上下文设计模式也与此相关。无需显式使用SynchronizationContext
<代码>等待
默认情况下会自动执行。谢谢。看起来我有点太偏执了。我会更正我的答案。@MarkShevchenko但我找不到HttpContext.cs文件中使用的ThreadStatic
属性。它实际在哪里使用@rejnev我的意思是,您可能需要在代码中使用ThreadStatic字段,例如在域或数据访问层中。这些层可用于后端,例如在执行后台数据处理的控制台应用程序中。ThreadStatic字段在控制台应用程序中运行良好。但一旦你开始在web应用程序中使用此代码,可能会有副作用。这并不意味着副作用是必要的,但它们是可能的。因此,一般规则是——如果你不知道自己在做什么,就不要在域/数据访问层中使用它们。@rejnev据我所知,ThreadStatic是一种相对高级的构造。HttpContext可能会将自身附加到线程,但它是在较低的级别上附加的。除了HttpContext.Current
似乎没有使用该属性之外,它的实现似乎要复杂得多。当然,属性不能直接应用ThreadStatic,只能应用字段。但在它的实现中必须有线程本地存储。