AsyncLocal
Conveying Context with AsyncLocal
Represents ambient data that is local to a given asynchronous control flow, such as an asynchronous method.
It’s a static class that allows you to access a variable without having to pass it through the call stack.
It’s similar to CurrentPrincipal
and CurrentCulture
, and not quite the same as ThreadLocal
.
It’s thread-safe.
It works well with the async
/await
paradigm.
For example, a middleware could set something into AsyncLocal
, eg a correlation id or a user id,
and then later in the request, something could read it.
It’s accessed statically, so there’s no tight-coupling.
The magic happens in the property Value
, which looks like a simple property, but is actually a method doing the magic.
You would use it in a static class, like this:
1
2
3
4
5
6
7
8
9
10
public static class Foo
{
private static readonly AsyncLocal<string> _bar = new AsyncLocal<string>();
public static string Bar
{
get => _bar.Value;
set => _bar.Value = value;
}
}
And then you can access it wherever you like, eg your middleware might do:
1
Foo.Bar = "baz";
and at some random point later you can read Foo.Bar
As I said, the magic is that, although it looks like a static, it’s actually scoped to the current request (asynchronous control flow)