但是,ASP.NET在移动请求时不会迁移所有与线程相关的数据.微软要么忘记这样做,要么认为使用线程局部存储(通过ThreadStatic属性变得容易)只是编码ASP.NET自己应该做的事情.
基于快速谷歌搜索,在我看来,避免这个问题的唯一方法是依赖HttpContext.如果ASP.NET决定在请求中切换线程,则确实会迁移上下文,因此克服了这个问题.但它反而引发了一个全新的问题:它将您的应用程序逻辑与HttpContext联系起来,从而与Web上下文联系起来.这在所有情况下都是不可接受的(事实上,我认为这在大多数情况下是不可接受的).此外,由于HttpContext是密封的并且具有内部构造函数,因此您无法模拟或存根,因此您的逻辑也变得不可测试.
根据this (old) blog post,CallContext不起作用,这是非常令人愤怒的,因为调用上下文在概念上恰好是一个逻辑线程!
有一种简单的方法可靠地实现“per-LOGICAL-thread”隔离,它可以在asp.net上下文以及其他上下文中使用吗?
如果没有,有没有人知道一个解决问题的轻量级第三方框架? ASP.NET迁移线程时StructureMap是否正常运行?
我想要一个通用的答案,但是如果有人想知道,我正在看的具体用例是在SharePoint上下文中使用Entity Framework.遗憾的是,我们暂时坚持使用SP-2010和EF 3.5. EF基本上要求使用与最初读取的相同的上下文保存数据 – 否则您必须自己跟踪更改.我想介绍一个“当前模型”的概念.在处理每个HTTP请求时第一次调用模型时,应该对其进行实例化,然后在请求的持续时间内使用相同的模型实例.但是,如果在计时器作业的上下文中执行,依赖于“Model.Current”的代码也应该有效.我很好用计时器作业代码在完成它时显式处理模型(我想在SharePoint Web上下文中为HttpApplication.EndRequest的处理程序提供一个任务).
可能有理由不这样做,这也很有趣,但无论如何我真的很想知道在asp.net上下文中实现“逻辑线程隔离”的方法,因为它非常有用.
解决方法
如果我把所有事情都做对了,Logical CallContext即CallContext.LogicalGetData和CallContext.LogicalSetData可以让你真实地移植不可变数据,因为你生活在.NET 4.5之后的世界里.这种不可改变的限制是一个坚果,但仍然……方式去.