请考虑这些情景:
我试图找出一种方法来设置"逻辑线程"在"逻辑"期间可以一致访问的特定数据http请求,即如果数据是在" BeginExecute"中的线程上设置的。您将考虑的部分异步处理程序,该数据在" EndExecute" asnc处理程序的一部分,即使ASP.NET执行" EndExecute"部分在不同的OS / .Net线程上。
此外,我期待在" BeginExecute"中设置数据。如果第二个请求被分配了先前分配给第一个http请求的线程,那么当它在#34; BeginExecute"部分但是当第一个http请求进入异步操作时,该线程被释放(并且它可能仍在完成其异步操作)。
我相信"逻辑线程"或者"逻辑线程上下文"在.Net中实际上意味着相同的"逻辑"我提到的操作流程(而不是继续重新分配的底层OS / .Net线程)。如果从工作流角度来看,每个http请求都是一个新的"逻辑"操作(即使多个用户顺序或并行地调用相同的Web服务,每个请求都是一个新的和部分逻辑操作),并且在这个意义上," logical"操作是一次性的,不能重复。但是,相同的底层OS / .Net线程可以映射到" logical"根据他们的可用性到达时的操作。
此外,我想将此数据公开为HttpContext.Current类型的静态属性。对于某些人来说,这可能会让人感到惊讶,但如果您使用的是异步.asmx Web服务方法,则HttpContext.Current无法正常工作。我确信我已经阅读了网上的内容,其中说HttpContext.Current应该总是返回正确的HttpContext,但我在.asmx web-methods的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文档),以下是我的推论:
现在来问题:
一个很长的问题,有很多参考文献,但希望我的研究很好,答案也会让其他人受益。
答案 0 :(得分:0)
我试图找出一种方法来设置“逻辑”http请求期间可以一致访问的“逻辑线程”特定数据
唯一可行的选项是HttpContext.Current.Items
和逻辑CallContext
。
此外,我希望“BeginExecute”部分中的数据在任何OS / .Net线程上设置在后续的http请求中
HttpContext.Current.Items
将始终在新请求中清除,但您必须自行清除逻辑CallContext
数据。
如果您使用的是异步.asmx网络服务方法,则HttpContext.Current无法正常工作。
我觉得这很令人惊讶。我没有尝试过,但它应该可行 - 如果你在.NET 4.5上运行,目标是.NET 4.5(即,targetFramework
设置为4.5
web.config
),并且未使用async void
。
[ThreadStatic]
,线程局部数据槽,(非逻辑)CallContext
和ThreadLocal
都是线程特定的数据,不适用于异步代码。
我上面说的一切都是正确的。请更正我所做的任何和所有不正确的声明。
你的问题中有太多的文字。 Stack Overflow是一个Q& A网站,而不是指导网站。
我错过了.Net中的线程静态类型功能是否还有其他选项。
没有
CallContext.LogicalSetData / LogicalGetData是否将上下文数据传递给RPC调用
我不知道。试试吧,看看。
使用CallContext.LogicalSetData / LogicalGetData是否有任何缺点(性能明智或其他方面)。
有明显的性能影响。 .NET框架针对常见情况进行了高度优化(没有逻辑调用上下文数据)。
如果我使用logicalsetdata保存引用类型并稍后更改引用类型的状态会产生什么影响。
逻辑CallContext
具有浅拷贝写入行为。因此,任何类型的异步fork / join并发(即Task.WhenAll
)都将最终共享该状态。如果你使用ConfigureAwait(false)
,你也可能会遇到竞争条件。
要真正解决您的问题,我建议您首先查看为什么HttpContext.Current
无法正常工作;我的猜测(没有看到项目)是targetFramework
设置为4.0
而不是4.5
。 HttpContext.Current.Items
是最有效的选择,如果你能让它发挥作用。