async/await 与console(C#)

打印 上一主题 下一主题

主题 866|帖子 866|积分 2598

问题:

上一篇async/await 致WPF卡死问题(https://www.cnblogs.com/stephen2023/p/17725159.html),介绍主线程阻塞,async/await导致卡死问题,同样的代码在console下却并不会出现卡死。
  1.         static Stopwatch sw = new Stopwatch();
  2.         static void log(string message)
  3.         {
  4.             Console.WriteLine($"{sw.ElapsedMilliseconds}:{message} by Thread:{Thread.CurrentThread.ManagedThreadId}");
  5.         }
  6.         static void Main(string[] args)
  7.         {
  8.             sw.Start();
  9.             log("Main() Started!");
  10.             var t = getResult().Result;
  11.             log($"got result:{t}");
  12.             log("Main() is Ended!");
  13.             Console.ReadKey();
  14.         }
  15.         public static async Task<int> getResult()
  16.         {
  17.             await Task.Delay(1000);
  18.         log("get result is about to return");
  19.             return 10;
  20.         }
复制代码
并且await后的任务也是由“新线程”执行的,并非主线程执行。
分析:

对于如下含await的代码
  1. await FooAsync();
  2. RestOfMethod();
复制代码
可以类比于:
  1. var t = FooAsync();
  2. var currentContext = SynchronizationContext.Current;
  3. t.ContinueWith(delegate
  4. {
  5.     if (currentContext == null)
  6.         RestOfMethod();
  7.     else
  8.         currentContext.Post(delegate { RestOfMethod(); }, null);
  9. }, TaskScheduler.Current);
复制代码
WPF与Console不同的关键在于SynchronizationContext,对于WPF,继承了SynchronizationContextDispatcherSynchronizationContext 并重写了post方法,将委托任务交由UI线程处理,而console程序并没有,当前的SynchronizationContext为null,所以对于console程序await后续的任务任由执行await异步任务的线程执行,相当于上一篇的ConfigureAwait(false),主线程阻塞,并不会出现卡死现象。
 
 
 
翻译
搜索
复制

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

千千梦丶琪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表