原文地址,請閱讀原文: https://blog.lindexi.com/post/win10-uwp-%E5%BC%82%E6%AD%A5%E8%BD%AC%E5%90%8C%E6%AD%A5.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗
有很多方法都是異步,那么如何從異步轉到同步?
在本文開始,我必須告訴大家,這個方法可能立即死鎖,所以使用的時候需要滿足下面的條件
使用的條件
-
異步轉同步的線程不是 UI 線程
-
如果線程是UI線程,那么異步方法不能在另外一個線程。
看到這里也許你會疑惑,為何異步方法可以不在另一個線程?實際上對於 IO 等的異步方法,都是沒有創建線程,請看There Is No Thread
關於這條件是如何來的,請看使用 Task.Wait()?立刻死鎖(deadlock) - walterlv
使用方法
可以使用的方法需要獲得是否有返回值,返回值是否需要。
如果需要返回值,使用GetResults
如從文件夾獲取文件:
StorageFolder folder = StorageFolder.GetFolderFromPathAsync("").GetResults();
這是同步方法,幾乎不需要做什么修改
如果是沒有返回值或不需要返回值的,請看下面代碼
StorageFolder.GetFolderFromPathAsync("").AsTask().Wait();
假設一個方法是沒返回的,可以使用Wait
Foo().Wait(); private async Task Foo()
通過這個方法就可以把異步方法轉同步。
如果需要反過來,把同步轉異步,可以使用 同步方法轉異步
await Task.Run(() => { 寫你的代碼 });
使用Task.Wait
時需要小心死鎖
不會出現死鎖的代碼
直接在UI使用Task.Run
private void Button_OnClick(object sender, RoutedEventArgs e) { var n = Task.Run(() => { return 2; }).Result; }
使用Task.Delay
等待
private void Button_OnClick(object sender, RoutedEventArgs e) { Task.Delay(100).Wait(); }
即使使用方法,里面使用 io 也有可能死鎖
private void Button_OnClick(object sender, RoutedEventArgs e) { DoAsync().Wait(); } private async Task DoAsync() { // 調用這個方法在 10.0.17134 / 10.0.16299 概率的死鎖 // 在 10.0.17763 基本就會死鎖 await ApplicationData.Current.LocalFolder.CreateFileAsync("lin", CreationCollisionOption.ReplaceExisting); }
會出現死鎖的寫法
在UI使用異步會創建線程的方法
private void Button_OnClick(object sender, RoutedEventArgs e) { DoAsync().Wait(); } async Task DoAsync() { await Task.Run(() => { }); }
private void Button_OnClick(object sender, RoutedEventArgs e) { DoAsync().Wait(); } async Task DoAsync() { await Task.Delay(100); }
private void Button_OnClick(object sender, RoutedEventArgs e) { DoAsync().Wait(); } private async Task DoAsync() { await Task.Run( () => { ApplicationData.Current.LocalFolder.CreateFileAsync("123", CreationCollisionOption.ReplaceExisting).GetResults(); }); }
本文會經常更新,請閱讀原文: https://blog.lindexi.com/post/win10-uwp-%E5%BC%82%E6%AD%A5%E8%BD%AC%E5%90%8C%E6%AD%A5.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
如果你想持續閱讀我的最新博客,請點擊 RSS 訂閱,推薦使用RSS Stalker訂閱博客,或者前往 CSDN 關注我的主頁
本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含鏈接: https://blog.lindexi.com ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。如有任何疑問,請 與我聯系 。