HttpContext.Current是如何工作的?

18

这是一个比较难以表述的问题。我想知道每个请求如何为HttpContext.Current分配唯一的实例,而它又是一个静态对象?

谢谢!


2个回答

24

Current 不是一个静态变量,而是它的静态属性。Get 属性仅仅是一个静态方法,用于返回当前上下文。

ASP.NET 会将一些信息存储在当前线程中,您可以始终获取一个本地线程存储器来存储信息,这种信息仅在当前线程中是静态的,并且只能由当前线程中的任何方法访问。

所以 ASP.NET 会将一些本地信息存储在线程中,在该线程中执行 Http 上下文请求的应用程序,并且无论从哪里调用 Current 都会获取本地线程数据并获取所需信息。

您还可以查看 [ThreadStatic] 特性,它几乎以类似的方式处理事情。

更新

从 ASP.NET 4.5 开始,Current HttpContext 通过 CallContext 传递,而不是通过 [ThreadStatic],因此上下文在单个逻辑上下文中的异步调用中保持可用,而不是在当前线程中,因为每个异步调用可能会在不同的线程上结束。


除此之外,它还可以在不同的线程中工作(为同一请求提供服务),这也是使用HttpContext存储上下文值而不是使用线程的主要原因。 - Sheepy
Kelsey在下面提供了更准确的答案,应该被接受作为答案。HttpContext不仅使用Thread来保持,因为如果您的代码使用plinq或async,它将无法工作,例如。 - Sheepy
@Sheepy,看一下这个语句:“CallContext提供了一个与线程本地存储非常相似的服务(除了在远程调用期间CallContext可以执行一些额外的魔法)。”而且HttpContext.Current也不能在plinq和async中工作,而不需要编写任何额外的代码。虽然CallContext会在内部使用ThreadLocalStorage,但没有它就无法工作。所以在发表这样的评论之前,请先获取所有细节。如果您提供CallContext不使用ThreadLocalStorage的证据,我会同意您的观点。 - Akash Kava
只要它们在请求范围内执行(而不是在请求完成后挂起),它就可以与plink和async一起使用。我以前尝试过这个(plinq)并经常尝试(async),这就是为什么我对它的工作方式感兴趣(并偶然发现了这个线程)。我正在尝试为我构建的工具(从Java EE到.NET的CDI实现)实现类似的结果,但仅使用Thread无法实现,因为多线程编程在.NET中已变得非常普遍。 - Sheepy

10

您应该阅读这篇博客文章:

http://odetocode.com/Articles/112.aspx

以下内容应该对您感兴趣。如果不是很长,我会引述更多:

好奇的人们会想知道HttpContext.Current如何找到当前请求的上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接