[英]Thread Static, ASP.NET and Async handlers
Please consider these sceanrios: 请考虑这些sceanrios:
I am trying to figure out a way to set "logical thread" specific data that can be accessed consistently during a "logical" http request, ie if the data was set on the thread in the "BeginExecute" part of which-ever async handler you would consider, that data is available in the "EndExecute" part of that asnc handler even if ASP.NET executes the "EndExecute" part on a different OS/.Net thread. 我试图找出一种方法来设置“逻辑”特定数据,这些数据可以在“逻辑”http请求期间一致地访问,即,如果数据是在“BeginExecute”部分中的线程中设置的,那么该异步处理程序你会想,即使ASP.NET在不同的OS / .Net线程上执行“EndExecute”部分,该数据也可以在该asnc处理程序的“EndExecute”部分中获得。
Moreover, I am expecting that the data set in the "BeginExecute" part on whatever OS/.Net thread it was on is NOT available on a subsequent http request if the second request is assigned the thread that was earlier assigned to first http request when it was in "BeginExecute" portion but this thread freed up as the first http request went in its async operation (and its possibly still completing its async operation). 此外,我希望在第二个请求被分配给先前分配给第一个http请求的线程的时候,在随后的http请求中,在“BeginExecute”部分中设置的任何OS / .Net线程中的数据都不可用。它位于“BeginExecute”部分,但是当第一个http请求进入异步操作时,该线程被释放(并且它可能仍在完成其异步操作)。
I believe the word "logical thread" or "logical thread context" in .Net actually means the same "logical" flow of operation that I have mentioned (and not the underlying OS/.Net thread that keeps getting re-assigned). 我相信.Net中的“逻辑线程”或“逻辑线程上下文”这个词实际上意味着我提到的相同的“逻辑”操作流程(而不是继续重新分配的底层OS / .Net线程)。 If you look at it from a workflow perspective, each http request is a new "logical" operation (even if multiple users invoke the same web-service sequentially or in parallel, each request is a new and separte logical operation), and in this meaning, the "logical" operation is one-time and cannot repeat.
如果从工作流角度来看,每个http请求都是一个新的“逻辑”操作(即使多个用户按顺序或并行调用相同的Web服务,每个请求都是一个新的和部分逻辑操作),并且在此意思是,“逻辑”操作是一次性的,不能重复。 However the same underlying OS/.Net threads can be mapped to "logical" operations as they arrive based on their availability.
但是,相同的底层OS / .Net线程可以根据其可用性到达时映射到“逻辑”操作。
Additionally I want to expose this data as HttpContext.Current sort of static property. 另外,我想将此数据公开为HttpContext.Current类的静态属性。 To some people this may come as a surprise, but HttpContext.Current does not work correctly if you are using for example async .asmx web-service methods.
对于某些人来说,这可能会让人感到惊讶,但如果您使用的是异步.asmx Web服务方法,则HttpContext.Current无法正常工作。 I am sure I have read content on web which says HttpContext.Current should always return correct HttpContext, but I have seen it as null in EndExecuteMethod of .asmx web-methods.
我确信我已经阅读了网上的内容,其中说HttpContext.Current应该总是返回正确的HttpContext,但我在.asmx web-methods的EndExecuteMethod中看到它为null。 It would be great if somecan can confirm if I am right in making my last statement, but this statement is not the overall question I am trying to ask here.
如果有人可以确认我是否正确地做出我的最后陈述,那将是很好的,但这个陈述不是我在这里要问的整体问题。
After reading a good amount of literature (eg 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 and more including MSDN docs), here are my inferences: 在阅读了大量文献后(例如log4net.ThreadContext和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文档),以下是我的推论:
Now come the questions: 现在来问题:
A long question with lots of references, but hopefully I did my research well and the answers would benefit other people too. 一个很长的问题,有很多参考文献,但希望我做得很好,答案也会让其他人受益。
I am trying to figure out a way to set "logical thread" specific data that can be accessed consistently during a "logical" http request
我试图找出一种方法来设置“逻辑”特定数据,这些数据可以在“逻辑”http请求期间一致地访问
The only possible options are HttpContext.Current.Items
and the logical CallContext
. 唯一可能的选项是
HttpContext.Current.Items
和逻辑CallContext
。
Moreover, I am expecting that the data set in the "BeginExecute" part on whatever OS/.Net thread it was on is NOT available on a subsequent http request
此外,我期望在其上的任何OS / .Net线程的“BeginExecute”部分中设置的数据在随后的http请求中不可用
HttpContext.Current.Items
will always be cleared on a new request, but you'll have to clear the logical CallContext
data yourself. HttpContext.Current.Items
将始终在新请求中清除,但您必须自己清除逻辑CallContext
数据。
HttpContext.Current does not work correctly if you are using for example async .asmx web-service methods.
如果您使用的是异步.asmx Web服务方法,则HttpContext.Current无法正常工作。
I find this surprising. 我觉得这很令人惊讶。 I haven't tried it, but it should work - if you are running on .NET 4.5, targeting .NET 4.5 (ie, have
targetFramework
set to 4.5
in your web.config
), and aren't using async void
. 我没有尝试过,但它应该工作 - 如果你在.NET 4.5上运行,目标是.NET 4.5(即,在
web.config
中将targetFramework
设置为4.5
),并且没有使用async void
。
[ThreadStatic]
, thread-local data slots, (non-logical) CallContext
, and ThreadLocal
are all thread-specific data, and will not work for asynchronous code. [ThreadStatic]
,线程本地数据槽,(非逻辑) CallContext
和ThreadLocal
都是线程特定的数据,不适用于异步代码。
Is everything I have said above correct.
我上面说的一切都是正确的。 Please correct any and all incorrect claims I have made.
请更正我所做的任何和所有不正确的声明。
There is really way too much text in your question. 你的问题中有太多的文字。 Stack Overflow is a Q&A site, not a mentoring site.
Stack Overflow是一个问答网站,而不是指导网站。
Are there any other options available for thread static kind of feature in .Net that I missed.
我错过了什么其他选项可用于.Net中的线程静态类型的功能。
No. 没有。
Does CallContext.LogicalSetData/LogicalGetData pass on the context data to RPC calls
CallContext.LogicalSetData / LogicalGetData是否将上下文数据传递给RPC调用
I have no idea. 我不知道。 Try it and see.
试试看吧。
Are there any downsides (performance wise or otherwise) of using CallContext.LogicalSetData/LogicalGetData.
使用CallContext.LogicalSetData / LogicalGetData是否有任何缺点(性能明智或其他方面)。
There's a definite performance hit. 有明显的性能影响。 The .NET framework is highly optimized for the common case (no logical call context data).
.NET框架针对常见情况(无逻辑调用上下文数据)进行了高度优化。
what's the impact if I save a reference type using logicalsetdata and later change the state of the reference type.
如果我使用logicalsetdata保存引用类型并稍后更改引用类型的状态会产生什么影响。
The logical CallContext
has shallow-copy-on-write behavior. 逻辑
CallContext
具有浅拷贝写入行为。 So, any kind of asynchronous fork/join concurrency (ie, Task.WhenAll
) will end up sharing that state. 因此,任何类型的异步fork / join并发(即
Task.WhenAll
)最终都会共享该状态。 If you use ConfigureAwait(false)
, you could also end up with race conditions. 如果您使用
ConfigureAwait(false)
,您也可能最终遇到竞争条件。
To actually solve your problem, I recommend you first look into why HttpContext.Current
doesn't work as expected; 为了真正解决您的问题,我建议您首先了解为什么
HttpContext.Current
不能按预期工作; my guess (without seeing the project) is that targetFramework
is set to 4.0
instead of 4.5
. 我的猜测(没有看到项目)是
targetFramework
设置为4.0
而不是4.5
。 HttpContext.Current.Items
is the most performant choice if you can get it working. HttpContext.Current.Items
是最高性能的选择,如果你可以让它工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.