序
部落客簡單數了下自己發佈過的非同步文章,已經斷斷續續 8 篇了,這次我想以 async 的回傳類型為例,單獨談談。
非同步方法有三個可能的回傳類型:Task
什麼時候需要使用哪一種回傳類型,具體情況需要具體分析。如果使用不當,程式的執行結果也許不是你想要的,下面我們就來好好談談如何針對不同的情況選擇不同的返回類型。
Task
【記住】當你加入 async 關鍵字後,需要傳回一個將用於後續操作的對象,請使用 Task
Task
在下面的範例中,GetDateTimeAsync 非同步方法包含一個傳回目前時間的 return 語句。 因此,方法宣告必須指定 Task
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 傳回的任務中的 DateTime 類型值。
async Task CallAsync() { //在另一个异步方法的调用方式 //DateTime now = await GetDateTimeAsync(); //换种方式调用 Task<DateTime> t = GetDateTimeAsync(); DateTime now = await t; }
透過 CallAsync 方法對 GetDateTimeAsync 方法的調用,對非立即等待的方法 GetDateTimeAsync 的調用返回 Task
這次我示範不同的變量,你可以自己對比下結果是否相同:
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}"); }
【注意】Result 屬性為鎖定屬性。 如果你在其任務完成之前嘗試存取它,目前處於活動狀態的執行緒將被阻止,直到任務完成且值為可用。 在大多數情況下,你應該透過使用 await 來存取屬性值,而不是直接存取屬性。
Task
不包含 return 語句或包含不傳回運算元的 return 語句的非同步方法通常具有傳回型別 Task。 如果被編寫為非同步運行,這些方法將為傳回 void 的方法。 如果在非同步方法中使用 Task 傳回類型,呼叫方法可以使用 await 運算子暫停呼叫方的完成,直到被呼叫的非同步方法結束。
請看範例:
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 傳回型別也可用於取代傳回 void 的方法,或是用於執行可分類為"呼叫後不管了"活動的方法。 但是,你應盡可能地回傳 Task,因為不能 await 回傳 void 的非同步方法。 這種方法的任何呼叫方只能夠繼續完成,而無需等待呼叫的非同步方法完成,且呼叫方必須獨立於非同步方法產生的任何值或異常。
傳回 void 的非同步方法的呼叫方無法捕獲從該方法引發的異常,且此類未經處理的異常可能會導致應用程式故障。 如果傳回 Task 或 Task
現在,異常也可以使用 await 了,請移步到這裡 《回眸 C# 的前世今生 - 見證 C# 6.0 的新語法特性》。
void 回傳值範例:
private async void button1_Click(object sender, EventArgs e) { //启动进程并等待完成 await Task.Delay(100); }
以上就是C#基礎回顧Async 的回傳類型的內容,更多相關內容請關注PHP中文網(www.php.cn)!