有四个因素共同作用,导致您所询问的行为:
- HttpContext是一个实例对象,其引用可以在
HttpContext.Current
中找到
- 线程也是一个实例对象,其引用可以在
Thread.CurrentThread
中找到
Thread.CurrentThread
是静态的,但在每个线程中引用不同的Thread
对象
HttpContext.Current
实际上是Thread.CurrentThread.ExecutionContext.IllogicalCallContext.HostContext
从以上假设中我们可以得出以下结论:
- 因为
HttpContext
是一个实例对象,而不是静电,所以我们需要它的引用来访问它
- 因为
HttpContext.Current
实际上指向Thread.CurrentThread
上的属性,所以将Thread.CurrentThread
更改为不同的对象可能会更改HttpContext.Current
- 因为
Thread.CurrentThread
'在切换线程时会发生变化,所以HttpContext.Current
在切换线程时也会发生变化(在本例中,HttpContext.Current
变为null).
综上所述,是什么原因导致HttpContext.Current
在新的线程中不起作用?切换线程时发生的Thread.CurrentThread
引用更改会更改HttpContext.Current
引用,这会阻止我们访问所需的HttpContext实例.
重申一下,这里唯一的神奇之处就是Thread.CurrentThread
在每个线程中引用不同的对象.HttpContext的工作方式与任何其他实例对象一样.因为同一AppDomain中的线程可以引用相同的对象,所以我们所要做的就是将HttpContext的引用传递给我们的新线程.没有要加载的上下文信息或类似的内容.(将HttpContext传递给其他线程有一些相当严重的潜在trap ,但没有什么可以阻止您这样做).
在研究过程中,我发现了一些最后的旁注:
在某些情况下,线程的ExecutionContext从一个线程"流动"(复制)到另一个线程.那么,为什么HttpContext没有"流"到我们的新线程?因为HttpContext没有实现iLogicThreadAffinative接口.存储在ExecutionContext中的类只有在实现iLogicThreadAffinative时才会流动.
ASP.NET将HttpContext从一个线程移动到另一个线程(线程敏捷性),如果它没有流动?我不完全确定,但看起来它可能在HttpApplication.OnThreadEnter()
分钟内通过.