I read about AsyncLocal<T>
from the MSDN documentation, but one point is still not clear for me.
I'm working on something like a context-bound caching/memoization, which has the simple purpose of storing data across a logical request. This is similar to the old HttpContext.Current
, where data is stored across a request and will be released at the end of the request. In my case, however, I want to be environment agnostic, so the implementation isn't bound to e.g. ASP.NET MVC, ASP.NET Core, WCF, etc., while still have the ability to store and retrieve the data which is bound to the logical request without sharing it across logically different requests.
To simplify my code according to question, it looks somewhat like this:
class ContextualStorageAccessor
{
// ConcurrentDictionary since it's okay if some parallel operations are used per logical request
private readonly AsyncLocal<ConcurrentDictionary<string, object>> _csm = new AsyncLocal<ConcurrentDictionary<string, object>>();
public ConcurrentDictionary<string, object> Storage
{
get
{
if (_csm.Value != null)
return _csm.Value;
_csm.Value = new ConcurrentDictionary<string, object>();
return _csm.Value;
}
}
}
The lifecycle of ContextualStorageAccessor
is a singleton.
And now the question: Will I have a unique instance of Value
per request? In other words, do I need to continue assigning a default value to _csm.Value
manually? Or I can rely on the type of application itself (e.g., ASP.NET MVC, WCF, etc.) which will take care of it?
Or, to rephrase: Where is the end of the "async flow" and does the ExecutionContext
guarantee unique values per logical call which will be automatically invalidated—in a simple scenario null
will be assigned to AsyncLocal.Value
—by the end of the logical call (for ASP.NET MVC, a web request; for WCF, an operation) if AsyncLocal.Value
is used?