请考虑以下情况:
我正在尝试找出一种设置“逻辑线程”特定数据的方法,该数据可以在“逻辑” http请求期间一致地访问,即,如果该数据是在任何异步处理程序的“BeginExecute”部分中的线程上设置的您会认为,即使ASP.NET在其他OS/.Net线程上执行“EndExecute”部分,该asnc处理程序的“EndExecute”部分中的数据仍然可用。
而且,我期望如果第二个请求被分配了先前分配给第一个http请求的线程,则在随后的http请求上,无论其处于哪个OS/.Net线程上的“BeginExecute”部分中的数据集都不可用。它在“BeginExecute”部分中,但是随着第一个http请求进入其异步操作(并且可能仍在完成其异步操作)时,此线程释放了。
我相信.Net中的“逻辑线程”或“逻辑线程上下文”一词实际上意味着与我已经提到的相同的“逻辑”操作流程(而不是不断重新分配的底层OS/.Net线程)。如果从工作流的角度来看它,则每个http请求都是一个新的“逻辑”操作(即使多个用户依次或并行调用同一Web服务,每个请求也是一个新的分离的逻辑操作),在这种情况下意思是,“逻辑”操作是一次性的,不能重复。但是,相同的基础OS/.Net线程在到达时可以根据其可用性映射为“逻辑”操作。
另外,我想将此数据公开为HttpContext.Current静态属性。对于某些人来说,这可能令人惊讶,但是HttpContext.Current如果您使用的是异步.asmx Web服务方法,则无法正常工作。我确定我已经在Web上阅读了内容HttpContext.Current应该总是返回正确的HttpContext,但是我已经在.asmx Web方法的EndExecuteMethod中将其视为null。如果有人可以确认我的发言是否正确,那就太好了,但这不是我要在这里提出的全部问题。
阅读了大量文献(例如What is the difference between log4net.ThreadContext and log4net.LogicalThreadContext?,http://msmvps.com/blogs/jon_skeet/archive/2010/11/08/the-importance-of-context-and-a-question-of-explicitness.aspx,http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html等,包括MSDN文档)后,以下是我的推断:
现在出现问题:
一个漫长的问题,有很多引用文献,但希望我做得很好,并且答案也会对其他人有益。
最佳答案
唯一可能的选项是HttpContext.Current.Items
和逻辑CallContext
。
始终会在收到新请求时清除HttpContext.Current.Items
,但您必须自己清除逻辑CallContext
数据。
我觉得这很奇怪。我还没有尝试过,但是它应该可以工作-如果您是在.NET 4.5上运行,以.NET 4.5为目标(即在targetFramework
中将4.5
设置为web.config
),并且没有使用async void
。[ThreadStatic]
,线程本地数据插槽,(非逻辑)CallContext
和ThreadLocal
都是特定于线程的数据,不适用于异步代码。
您的问题中确实有太多文字。堆栈溢出是一个问答站点,而不是指导站点。
不。
我不知道。试试看。
有一定的性能影响。 .NET框架针对常见情况(无逻辑调用上下文数据)进行了高度优化。
逻辑CallContext
具有写浅复制行为。因此,任何类型的异步fork/join并发(即Task.WhenAll
)最终都会共享该状态。如果您使用ConfigureAwait(false)
,那么您也可能会遇到竞争条件。
为了真正解决您的问题,我建议您首先研究为什么HttpContext.Current
无法按预期工作;我的猜测(没有看到项目)是targetFramework
设置为4.0
而不是4.5
。如果可以使用HttpContext.Current.Items
,则它是性能最高的选择。