1. 程式人生 > >15.3 Task 語法和語義

15.3 Task 語法和語義

15.3.1 宣告非同步方法和返回型別

1         async static void GetStringAsync()
2         {
3             using (var client = new HttpClient())
4             {
5                 Task<string> task = client.GetStringAsync("https://www.baidu.com/");
6                 string result = await task;
7             }
8 }

15.3.3 可等待模式

  大量工作都是通過模式來表示的,這有點類似於 foreach 和LINQ查詢。為了更清晰地描述
該模式的輪廓,假設存在一些相關的介面(但實際並沒有)。稍後我會介紹真實情況,現在先來
看看虛構的介面:

 1     /// <summary> 為包含返回值的非同步操作 建立的虛擬的介面  警告:這些並不存在 自定義的</summary>
 2     public interface IAwaitable<T>
 3     {
 4         IAwaiter<T> GetAwaiter();
5 } 6 7 public interface IAwaiter<T> : INotifyCompletion 8 { 9 bool IsCompleted { get; } 10 T GetResult(); 11 12 //從INotifyCompletion 繼承 13 //void OnCompleted(Action continuation); 14 } 15 16 /// <summary> 為沒有返回值的非同步操作 建立的虛擬的介面
</summary> 17 public interface IAwaitable 18 { 19 IAwaiter GEtAwaiter(); 20 } 21 22 public interface IAwaiter : INotifyCompletion 23 { 24 bool IsCompleted { get; } 25 void GetResult(); 26 27 //從INotifyCompletion 繼承 28 //void OnCompleted(Action continuation); 29 }

  前面講述了什麼樣的表示式可以作為 await 關鍵字的目標,不過整個表示式本身也同樣擁有
一個有趣的型別:如果 GetResult() 返回 void ,那麼整個 await 表示式就沒有型別,而只是一
個獨立的語句。否則,其型別與 GetResult() 的返回型別相同。
  例如, Task<TResult>.GetAwaiter() 返回一個 TaskAwaiter<TResult> ,其 GetResult()
方法返回 TResult 。(希望你不會感到奇怪。)根據 await 表示式的型別規則,我們可以編寫這樣
的程式碼:

1             using (var client = new HttpClient())
2             {
3                 Task<string> task = client.GetStringAsync("https://www.baidu.com/");
4                 string result = await task;
5             }

  這裡的 await 表示式不會返回任何型別的值,因此不能將其分配給變數,或作為方法實參進
行傳遞,也不能執行其他任何將表示式作為值的相關操作。
  需要注意的是,由於 Task 和 Task<TResult> 都實現了可等待模式,因此可以在一個非同步方
法內呼叫另一個非同步方法:

 1         public async Task<int> Foo()
 2         {
 3             string bar = await BarAsync();
 4             //顯然通常會更復雜
 5             return bar.Length;
 6         }
 7         public async Task<string > BarAsync()
 8         {
 9             //一些非同步程式碼,可能會呼叫更多非同步方法
10         }

  組合非同步操作正是非同步特性大放異彩的一個方面。進入非同步模式(mode)後,就可以很輕
鬆地保持這種模式,編寫自然流暢的程式碼。