async/await 与console(C#)

  • async/await 与console(C#)已关闭评论
  • 108 次浏览
  • A+
所属分类:.NET技术
摘要

上一篇async/await 致WPF卡死问题(https://www.cnblogs.com/stephen2023/p/17725159.html),介绍主线程阻塞,async/await导致卡死问题,同样的代码在console下却并不会出现卡死。


问题:

上一篇async/await 致WPF卡死问题(https://www.cnblogs.com/stephen2023/p/17725159.html),介绍主线程阻塞,async/await导致卡死问题,同样的代码在console下却并不会出现卡死。

        static Stopwatch sw = new Stopwatch();          static void log(string message)         {             Console.WriteLine($"{sw.ElapsedMilliseconds}:{message} by Thread:{Thread.CurrentThread.ManagedThreadId}");         }          static void Main(string[] args)         {             sw.Start();             log("Main() Started!");             var t = getResult().Result;             log($"got result:{t}");             log("Main() is Ended!");             Console.ReadKey();          }          public static async Task<int> getResult()         {             await Task.Delay(1000);         log("get result is about to return");             return 10;         }

并且await后的任务也是由“新线程”执行的,并非主线程执行。

分析:

对于如下含await的代码

await FooAsync(); RestOfMethod();

可以类比于:

var t = FooAsync(); var currentContext = SynchronizationContext.Current; t.ContinueWith(delegate {     if (currentContext == null)         RestOfMethod();     else         currentContext.Post(delegate { RestOfMethod(); }, null); }, TaskScheduler.Current);

WPF与Console不同的关键在于SynchronizationContext,对于WPF,继承了SynchronizationContextDispatcherSynchronizationContext 并重写了post方法,将委托任务交由UI线程处理,而console程序并没有,当前的SynchronizationContext为null,所以对于console程序await后续的任务任由执行await异步任务的线程执行,相当于上一篇的ConfigureAwait(false),主线程阻塞,并不会出现卡死现象。

 

 

 

翻译

搜索

复制