CallContext vs ThreadStatic
Very often a request will use the same thread throughout, but it certainly won't always be the case - ASP.NET exhibits thread agility. There's an old in-depth blog article about the matter from 2005, but as of .NET 4.5 things are rather better.
CallContext.LogicalGetData() vs ThreadLocal/ThreadStatic
Yes, the logical call context will work as an async-local.
AsyncLocal<T>
uses the logical call context on the full .NET framework - it just has a nicer API and will work with the upcoming .NET Core platform while the logical call context will not.
Remember to only store immutable data, as I describe on my blog.
Also, there is a definite performance impact with async-local values. It would almost definitely be more performant to pass the parameter explicitly, perhaps as part of your own RequestContext
type. ASP.NET vCore is moving away from HttpContext.Current
; it still has the concept of HttpContext
, but it doesn't act as an async local anymore - it's passed explicitly.
Can I rely on CallContext using Web API?
You lose your CallContext if ASP.Net switches threads. In an asynchronous model, the asp.net task scheduler will take care of joining async calls back to a request thread with the same HttpContext, but not necessarily the same thread.
Example: A request starts and then you go off to asynchronously wait for some slow IO before returning - while you're waiting for that slow IO there's no reason for your request thread to be sitting around doing nothing so it may get used for another request.
ASP.Net is a big exercise in Thread Agility
(google it), and there is also a great discussion about this here: CallContext vs ThreadStatic vs HttpContext
Can data stored in CallContext leak between requests?
In an MVC app I need to store some user data to verify if he has all
the rights to access some pages (like he is an owner of an object
etc.).
What you are looking for is HttpContext.Session
, as @Ron's answer suggest. You'd need to enable the session support.
OTOH, the lifetime of HttpContext.Items
is limited to a given HTTP request, it does not flow between requests. Some HTTP protocol textual state data (e.g. cookies) will be flowed via HttpContext.Current.Request
.
Can data stored in CallContext leak between requests?
If you still like to know if the logical call context data (CallContext.LogicalGetData
/ CallContext.LogicalSetData
) flows between different HTTP requests, the answer would be no. If it did, that'd be a serious security hole, as different requests may come from different users.
It does however flow between threads within the same request, so for that matter it can be used as a substitution for ThreadLocal
. Aalthough, use with care, as there's copy-on-write behavior, check Stephen Cleary's blog for more details. You may only need it if you use asynchronous controller methods and async
/await
(or ContinueWith
etc).
ThreadStatic in async/await - LogicalCallContext doesn't flow outside of async method?
The cause was in that LogicalCallContext
is only passed deeper so when the execution returns from LockAsync
the stored context is lost.
I ended up wrapping LockAsync
with non-async method version:
public Task<DisposableAction> EnterAsync()
{
container = new Container(); // class
// I'm using AsyncLocal instead of LogicalCallContext but it's pretty much the same thing
_entered.Value = container;
return EnterAsync(container);
}
async Task<DisposableAction> EnterAsync(Container container)
{
// real work
}
This way LogicalCallContext
is set on the same async level as a caller method and not lost with return.
Related Topics
Show Controls Added Programmatically in Winforms App in Design View
How to Implement Custom Authentication in ASP.NET MVC 5
Nsubstitute - Testing for a Specific Linq Expression
How to Get a Type's Alias Through Reflection
Accessing All the Nodes in Treeview Control
Rounding Integers to Nearest Multiple of 10
Print List of Objects to Console
What to Use: Var or Object Name Type
How to Split a String into Multiple Values
How to Show a Image in Database in the Image Control of ASP.NET
Why How to Not Edit a Method That Contains an Anonymous Method in the Debugger
Using Bindingoperations.Enablecollectionsynchronization
JSONconvert.Serializeobject Always Return {} in Xamarinforms
Wpf Error 40 Bindingexpression Path Error: Property Not Found on 'Object'