問題: 上一篇async/await 致WPF卡死問題(https://www.cnblogs.com/stephen2023/p/17725159.html),介紹主線程阻塞,async/await導致卡死問題,同樣的代碼在console下卻並不會出現卡死。 static Stopwatch sw ...
問題:
上一篇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,繼承了SynchronizationContext為DispatcherSynchronizationContext 並重寫了post方法,將委托任務交由UI線程處理,而console程式並沒有,當前的SynchronizationContext為null,所以對於console程式await後續的任務任由執行await非同步任務的線程執行,相當於上一篇的ConfigureAwait(false),主線程阻塞,並不會出現卡死現象。
翻譯
搜索
複製