Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make AsyncLocal flow to siblings?

This is a very simple example I expect to work but...

    static AsyncLocal<bool> _value = new AsyncLocal<bool>();

    static void Main(string[] args)
    {
        A().Wait();
    }

    static async Task A()
    {
        await B();
        await C();
    }

    static async Task B()
    {
        _value.Value = true;
    }

    static async Task C()
    {
        if (!_value.Value) throw new Exception();
    }

So is there a possibility to store something inside method B in a way so that a value is available in C? I need it to be passed only through async flow (no ThreadStatic please).

like image 354
Vlad Avatar asked May 18 '16 17:05

Vlad


1 Answers

So this is what I discovered:

  • AsyncLocal are only transfered one way - from outer-level to inner-level async methods so I added a B_Start method which initializes the local at a "top" level.
  • Changes inside an inner method are not transferred back even for already initialized locals but you can mutate fields on a reference-type container.

Working code:

    class Container<T>
    {
        public T Value { get; set; }
    }
    static AsyncLocal<Container<bool>> _value = new AsyncLocal<Container<bool>>();

    static void Main(string[] args)
    {
        A().Wait();
    }

    static async Task A()
    {
        await B_Start();
        await C();
    }

    static Task B_Start()
    {
        _value.Value = new Container<bool>();
        return B();
    }

    static async Task B()
    {
        _value.Value.Value = true;
    }

    static async Task C()
    {
        if (!_value.Value.Value) throw new Exception();
    }
like image 78
Vlad Avatar answered Oct 12 '22 21:10

Vlad