Jak zabránit úkolu z dědění rodič úkol kontext Logical volání

hlasů
0

Snažím se používat AsyncLocal jako náhrada za závitem lokální paměti při použití Task.Run () a asynchronní metody. Problém mám, je, že i třeba níže uvedený kód pro tisk

from t1 t1
from t1 t1
from t2 t2
from t2 t2

To by bylo chování při použití tématu místního úložiště, ale místo toho jsem dostat tento výstup.

from t1 t1
from t1 t1
from t2 t1
from t2 t1

Příklad číslo:

public class ClientClass {

   public static void Main() 
   {
      AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
      var t1 = Task.Run( async () => {
          string a = _asyncLocalString.Value;
          if (a == null) {
              _asyncLocalString.Value = t1;
          }
          a = _asyncLocalString.Value;
          Console.WriteLine(from t1  + a);
          await Task.Delay(10);
          string b = _asyncLocalString.Value;
          Console.WriteLine(from t1  + b);
          var t2 = Task.Run( async () => {
              string aa = _asyncLocalString.Value;
              if (aa == null) {
                  _asyncLocalString.Value = t2;
              }
              aa = _asyncLocalString.Value;
              Console.WriteLine(from t2  + aa);
              await Task.Delay(10);
              string bb = _asyncLocalString.Value;
              Console.WriteLine(from t2  + bb);

          });
          await t2;
      });
      t1.Wait();
   }
} 
Položena 27/11/2018 v 18:03
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
1

Můžete potlačit proud před voláním Task.Run a obnovit ji po

public class ClientClass {

   public static void Main() 
   {
        AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
        var t1 = Task.Run(async () =>
        {
            string a = _asyncLocalString.Value;
            if (a == null)
            {
                _asyncLocalString.Value = "t1";
            }
            a = _asyncLocalString.Value;
            Console.WriteLine("from t1 " + a);
            await Task.Delay(10);
            string b = _asyncLocalString.Value;
            Console.WriteLine("from t1 " + b);

            ExecutionContext.SuppressFlow();

            var t2 = Task.Run(async () =>
            {
                string aa = _asyncLocalString.Value;
                if (aa == null)
                {
                    _asyncLocalString.Value = "t2";
                }
                aa = _asyncLocalString.Value;
                Console.WriteLine("from t2 " + aa);
                await Task.Delay(10);
                string bb = _asyncLocalString.Value;
                Console.WriteLine("from t2 " + bb);

            });

            ExecutionContext.RestoreFlow();

            await t2;
        });
        t1.Wait();
   }
} 

dát

from t1 t1
from t1 t1
from t2 t2
from t2 t2
Odpovězeno 29/11/2018 v 04:32
zdroj uživatelem

hlasů
0

Jediný způsob, jak vím, je použití ThreadPool.UnsafeQueueUserWorkItem :

public class ClientClass {

   public static void Main() 
   {
        AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
        var t1 = Task.Run(async () =>
        {
            string a = _asyncLocalString.Value;
            if (a == null)
            {
                _asyncLocalString.Value = "t1";
            }
            a = _asyncLocalString.Value;
            Console.WriteLine("from t1 " + a);
            await Task.Delay(10);
            string b = _asyncLocalString.Value;
            Console.WriteLine("from t1 " + b);
            var tcs = new TaskCompletionSource<bool>();
            ThreadPool.UnsafeQueueUserWorkItem(async s =>
            {
                string aa = _asyncLocalString.Value;
                if (aa == null)
                {
                    _asyncLocalString.Value = "t2";
                }
                aa = _asyncLocalString.Value;
                Console.WriteLine("from t2 " + aa);
                await Task.Delay(10);
                string bb = _asyncLocalString.Value;
                Console.WriteLine("from t2 " + bb);
                ((TaskCompletionSource<bool>)s).SetResult(true);
            }, tcs);
            await tcs.Task;
        });
        t1.Wait();
   }
} 
Odpovězeno 28/11/2018 v 22:23
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more