【轉】C#異步轉同步



原文地址,請閱讀原文: https://blog.lindexi.com/post/win10-uwp-%E5%BC%82%E6%AD%A5%E8%BD%AC%E5%90%8C%E6%AD%A5.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗

 

有很多方法都是異步,那么如何從異步轉到同步?

在本文開始,我必須告訴大家,這個方法可能立即死鎖,所以使用的時候需要滿足下面的條件

使用的條件

  1. 異步轉同步的線程不是 UI 線程

  2. 如果線程是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(); }); } 

參見:使用 Task.Wait()?立刻死鎖(deadlock) - walterlv


本文會經常更新,請閱讀原文: 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 ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。如有任何疑問,請 與我聯系 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM