> For the complete documentation index, see [llms.txt](https://til.cazzulino.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://til.cazzulino.com/dotnet/asynclocal-never-leaks-and-is-safe-for-callcontext-like-state.md).

# AsyncLocal never leaks and is safe for CallContext-like state

Sometime ago I wrote on [How to migrate CallContext to .NETStandard and .NETCore](https://www.cazzulino.com/callcontext-netstandard-netcore.html), and one question mentioned that the values themselves might leak, which actually is not the case, as shown here, due to the "magic" that is AsyncLocal in combination with the [transient nature of the ExecutionContext](https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs#L133-L200):

```
static AsyncLocal<object> local = new AsyncLocal<object>();

async Task Main()
{
    WeakReference data = null;

    await Task.Run(() =>
    {
        var o = new object();
        data = new WeakReference(o);
        // We assign to the static async local, to see if it leaks.
        local.Value = o;
    });

    // After execution is finished, we do have a live reference still.
    System.Diagnostics.Debug.Assert(data.IsAlive == true);

    GC.Collect();

    // But a GC proves nobody is holding a strong reference to it.
    System.Diagnostics.Debug.Assert(data.IsAlive == false);
}

```
