亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

同步等待異步操作,為什么Wait()在這里凍結程序

同步等待異步操作,為什么Wait()在這里凍結程序

MMMHUHU 2019-11-05 10:25:52
我在尋找一個解釋,而不僅僅是一個解決方案。我已經知道了解決方案。盡管花了幾天時間研究有關基于任務的異步模式(TAP),異步和等待的MSDN文章,但我對某些更詳細的信息仍然感到困惑。我正在為Windows Store Apps編寫記錄器,并且希望同時支持異步和同步記錄。異步方法遵循TAP,同步方法應該隱藏所有這些內容,并且外觀和工作方式與普通方法類似。這是異步日志記錄的核心方法:private async Task WriteToLogAsync(string text){    StorageFolder folder = ApplicationData.Current.LocalFolder;    StorageFile file = await folder.CreateFileAsync("log.log",        CreationCollisionOption.OpenIfExists);    await FileIO.AppendTextAsync(file, text,        Windows.Storage.Streams.UnicodeEncoding.Utf8);}現在對應的同步方法...版本1:private void WriteToLog(string text){    Task task = WriteToLogAsync(text);    task.Wait();}看起來正確,但是不起作用。整個程序永久凍結。版本2:嗯..也許任務沒有開始?private void WriteToLog(string text){    Task task = WriteToLogAsync(text);    task.Start();    task.Wait();}這拋出 InvalidOperationException: Start may not be called on a promise-style task.版本3:嗯.. Task.RunSynchronously聽起來很有希望。private void WriteToLog(string text){    Task task = WriteToLogAsync(text);    task.RunSynchronously();}這拋出 InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.版本4(解決方案):private void WriteToLog(string text){    var task = Task.Run(async () => { await WriteToLogAsync(text); });    task.Wait();}這可行。因此,2和3是錯誤的工具。但是1?1有什么問題,與4有什么區別?是什么導致1凍結?任務對象有問題嗎?有沒有明顯的僵局?
查看完整描述

3 回答

?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

async從同步代碼中調用代碼可能非常棘手。


我在博客上解釋了造成這種僵局的全部原因。簡而言之,每個上下文的開頭都有一個默認保存的“上下文”,await用于恢復該方法。


因此,如果在UI上下文中調用await此async方法,則在完成時,該方法將嘗試重新輸入該上下文以繼續執行。不幸的是,使用Wait(或Result)的代碼將在該上下文中阻塞線程,因此該async方法無法完成。


避免這種情況的準則是:


使用ConfigureAwait(continueOnCapturedContext: false)盡可能多地。這使您的async方法可以繼續執行而不必重新輸入上下文。

一直使用async。使用await代替Result或Wait。

如果您的方法自然是異步的,那么(可能)您不應該公開同步包裝器。


查看完整回答
反對 回復 2019-11-05
  • 3 回答
  • 0 關注
  • 887 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號