Callcontext VS Threadstatic

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



Leave a reply



Submit