[C#] Await & Async初體驗

  • 2431
  • 0
  • 2018-01-23

從.NET 4.5開始新增了關鍵字 asyncawait

以下是其使用方式

因為專案需求會透過參數去取得server上的副檔名 .ashx的檔案,

而必須在接到參數後在後端去仿照前端發request的動作而牽扯到async和await.....

題外話

.ashx就是一種http處理常式(定義: 為了回應對 ASP.NET Web 應用程式所提出之要求而執行的處理序。最普通的處理常式是處理 .aspx 檔案的 ASP.NET 網頁處理常式。當使用者要求 .aspx 檔案時,會透過網頁處理常式處理要求。)

簡而言之, .ashx的檔案就是只不包含UI但是目的也是用來處理request

正題開始

做一個簡單的畫面測試,

按下Async按鈕他會幫我在TextArea的地方把文字串上去

protected async void btnAsync_OnClick(object sender, EventArgs e)
{
    //第一段
    txtUserId.Text = "\n Start";
    GetRemoteData();
    txtUserId.Text += "\n End";

    //第二段
    txtUserId.Text = "\n Start";
    txtUserId.Text += await GetRemoteDataAsync();   //呼叫自定義的GetRemoteDataAsync(), 注意回傳型態為Task<string>
    txtUserId.Text += "\n End";
}

private async void GetRemoteData()
{
    HttpClient hc = new HttpClient();
    var result = await hc.GetStringAsync("http://localhost:54395/RemoteString.ashx");
    txtUserId.Text += "\n" + result;
}
   
private async Task<string> GetRemoteDataAsync()
{
    HttpClient hc = new HttpClient();
    var result = await hc.GetStringAsync("http://localhost:54395/RemoteString.ashx");
    return result;
}

假設上述程式片段呼叫 http://localhost:54395/RemoteString.ashx 時需要一段時間處理,

那第一段程式的結果會是

Start

End

回傳result

原因是定義 GetRemoteData() 前面多了關鍵字async, 會被視為非同步的method,

所以並不會等到這行程式被執行完才執行 txtUserId.Text += "\n End"; , 因此會先印出 End

而在GetRemoteData()中的關鍵字await, var result = await hc.GetStringAsync("http://localhost:54395/RemoteString.ashx");

表示編譯器會在此行下斷點, 之後的程式都會在此行程式完成後再繼續執行

 

而第二段的結果如下

Start

回傳result

End

要注意的是在最後定義GetRemoteDataAsync()的地方其回傳型態為 Task<string>, 表示其為awaitable的method,

所以在註解第二段以 txtUserId.Text += await GetRemoteDataAsync(); 來呼叫,

之後的程式碼會等到await執行完後再繼續

 

非同步方法可有下列傳回型別:

簡單來說這個例子舉的方法會回傳string, 所以用 Task<string> 來當成傳回型別。

如果方法完成時未傳回任何有意義的值,則使用 Task。 也就是說,呼叫方法會傳回 Task,但是當 Task 完成時,等候 await 的任何 Task 運算式都會判斷值為 void

使用 void 傳回類型定義需要該傳回類型的事件處理常式。 傳回 void 之非同步方法的呼叫端無法等候它,而且無法攔截方法擲回的例外狀況。

 

引用參考: http://studyhost.blogspot.tw/2012/06/metro-style-appnet-45.html