程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> [C#] async 的三大返回類型,

[C#] async 的三大返回類型,

編輯:關於.NET

[C#] async 的三大返回類型,


async 的三大返回類型

  博主簡單數了下自己發布過的異步文章,已經斷斷續續 8 篇了,這次我想以 async 的返回類型為例,單獨談談。

  異步方法具有三個可讓開發人員選擇的返回類型:Task<TResult>、Task 和 void。 

  什麼時候需要使用哪一種返回類型,具體情況需要具體分析。如果使用不當,程序的執行結果也許並不是你想要的,下面我們就來好好談談如何針對不同的情況選擇不同的返回類型。

 

目錄

  • 返回類型 - Task<TResult> 
  • 返回類型 - Task
  • 返回類型 - void
  • 小結

 

一、返回類型 - Task<TResult> 

  【記住】當你添加 async 關鍵字後,需要返回一個將用於後續操作的對象,請使用 Task<TResult>。

 

    Task<TResult> 返回類型可用於 async 方法,其中包含指定類型 TResult

  在下面的示例中,GetDateTimeAsync 異步方法包含一個返回當前時間的 return 語句。 因此,方法聲明必須指定 Task<DateTime>

        async Task<DateTime> GetDateTimeAsync()
        {
            //Task.FromResult 是一個占位符,類型為 DateTime
            return await Task.FromResult(DateTime.Now);
        }

  

  調用 GetDateTimeAsync 方法:

        async Task CallAsync()
        {
            //在另一個異步方法的調用方式
            DateTime now = await GetDateTimeAsync();
        }

  當 GetDateTimeAsync 從 await 表達式中調用時,await 表達式將檢索存儲在由 GetDateTimeAsync 返回的 task 中的 DateTime 類型值。 

 

        async Task CallAsync()
        {
            //在另一個異步方法的調用方式
            //DateTime now = await GetDateTimeAsync();

            //換種方式調用
            Task<DateTime> t = GetDateTimeAsync();
            DateTime now = await t;
        }

  通過 CallAsync 方法對 GetDateTimeAsync 方法的調用,對非立即等待的方法 GetDateTimeAsync 的調用返回 Task<DateTime>。 該任務指派給示例中的 DateTime 的 Task 變量。 因為 DateTime 的 Task 變量是 Task<DateTime>,也就是說這裡的 TResult 就是 DateTime 類型。 在這種情況下,TResult 表示日期類型。 當 await 應用於 Task<DateTime>,await 表達式的計算結果為 Task<DateTime> 的 DateTime 類型的內容。同時,該值會分配給 now 變量。

 

  這次我演示不同的變量,你可以自己對比下結果是否相同:

        async Task CallAsync()
        {
            //在另一個異步方法的調用方式
            DateTime now = await GetDateTimeAsync();

            //換種方式調用
            Task<DateTime> t = GetDateTimeAsync();
            DateTime now2 = await t;
        
       //輸出的結果對比 Console.WriteLine($"now: {now}"); Console.WriteLine($"now2: {now2}"); Console.WriteLine($"t.Result: {t.Result}"); }

  

  我這邊可以給出的答案就是:結果是一樣的。

  【注意】task 的 Result 屬性為鎖定屬性。如果你在該 task 完成之前嘗試讀取該屬性值,會出現的結果是,當前處於活動狀態的 thread 將被阻塞,阻塞到該 task 完成且結果值為可用時。 在大多數情況下,你都應通過使用 await 訪問屬性值,而不是直接訪問該屬性。

 

二、返回類型 - Task

  【記住】你如果只是想知道執行的狀態,而不需要知道具體的返回結果時,請使用 Task。

 

  不包含 return 語句,或者說不包含返回值的 return 語句的 async 方法通常具有返回類型 Task。如果這樣的同步方法被編寫為 async 的,這些方法實際上也是返回 void 的方法。 如果在異步方法中使用 Task 返回類型,調用方法可以使用 await 運算符暫停調用方的完成,直至被調用的 async 方法結束。

 

  請看示例:

        async Task DelayAsync()
        {
            //Task.Delay 是一個占位符,用於假設方法正處於工作狀態。
            await Task.Delay(100);

            Console.WriteLine("OK!");
        }

  

  通過使用 await 語句而不是 await 表達式來調用和等待 DelayAsync 方法,類似於返回 void 的方法的調用語句。 await 運算符的應用程序在這種情況下不生成值。

  請看調用 DelayAsync 的示例。

            //調用和等待方法在同一聲明中
            await DelayAsync();

 

  現在,我用將調用和等待的方法進行分離:

            //分離
            Task delayTask = DelayAsync();

            await delayTask;        

 

三、返回類型 - void

  【記住】如果在觸發後,你不想管了,請使用 void。如事件處理程序。

 

  void 返回類型主要用在事件處理程序中。 void 返回類型還可用來替代不返回任何東西的方法,或者用於執行可分類為"調用後不管了"活動的方法。 但是,你都應盡可能地返回類型 Task ,因為,不能 await 返回類型為 void 的 async 方法。 async 方法的任何調用方只能夠繼續完成(意味著有可能會出現 thread 阻塞),而無需等待調用的 async 方法完成,並且調用方應該,或者說必須獨立於 async 方法生成的任何值或 exception。

  返回 void 的 async 方法的調用方無法 catch 從該方法引發的 exception,並且,這種未經處理的 exception 可能會導致你的程序出現難以發現的故障。 如果返回 Task 類型或 Task<TResult> 類型的 async 方法中出現 exception,這種 exception 將存儲於返回的任務中,並將在 await 該任務時再次觸發。也就是說,請盡量優先使用 Task<TResult> 和 Task,這樣,調用方才能從中讀取異常信息,並選擇如何處理。

  現在,異常也可以使用 await 了,請移步到這裡 《回眸 C# 的前世今生 - 見證 C# 6.0 的新語法特性》。

 

  void 返回值示例:

        private async void button1_Click(object sender, EventArgs e)
        {
            //啟動進程並等待完成
            await Task.Delay(100);
        }

 

小結

  • 當你添加 async 關鍵字後,需要返回一個將用於後續操作的對象,請使用 Task<TResult>;

  • 你如果只是想知道執行的狀態,而不需要知道具體的返回結果時,請使用 Task;

  • 如果在觸發後,你不想管了,請使用 void。

  • 請盡量優先使用 Task<TResult> 和 Task 作為 async 方法的返回類型。

 

異步編程的系列

 

 


【博主】反骨仔

【出處】http://www.cnblogs.com/liqingwen/p/6218994.html 

【參考】微軟官方文檔

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved