.NET 4.5 非同步功能 Async
如下圖所示按下button1事件執行ListBox加入開始時間及事件結束時間及取得物件的時間,可以看到下圖的顯示就是一個非同步的運算38秒開始及結束42秒才取得物件結果,所以程式在設計為了不讓UI等待回傳運算值可以繼續往下執行其它運算,就會採用非同步的寫法。
在還沒有 Async 關鍵字前的寫法如下,還要注意ListBox1 跨執行緒作業無效: 存取控制項 'listBox1' 時所使用的執行緒與建立控制項的執行緒不同,所以要用BeginInvoke來處理UI
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items .Add (DateTime .Now .ToString ()+"開始");
DownloadDataInBackground("https://www.google.com/");
listBox1.Items.Add(DateTime .Now .ToString ()+"結束");
}
public void DownloadDataInBackground(string address)
{
Action action = new Action(delegate
{
System.Net.WebClient clinet = new System.Net.WebClient();
var result = clinet.DownloadString("https://www.google.com/");
this.listBox1.BeginInvoke(new Action(() =>
{
listBox1.Items.Add(DateTime.Now.ToString() + result);
}));
});
action.BeginInvoke(null, null);
}
上面的程式是因為有了Action 關鍵字縮短了委派作業的寫法,但是在新的.NET 4.5 多了 async 跟 await 就不一樣了寫法也更簡潔了如下所示,也不用處理ListBox1 跨執行緒作業的問題
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items .Add (DateTime .Now .ToString ()+"開始");
GetData();
listBox1.Items.Add(DateTime .Now .ToString ()+"結束");
}
private async void GetData()
{
System.Net.Http.HttpClient http = new System.Net.Http.HttpClient();
var result =await http.GetAsync ("https://www.google.com/");
listBox1.Items.Add(DateTime .Now .ToString ()+result);
}
當然也可以寫成 async 函式回傳值,不過這種寫法要看使用場合,還不如上面用async 方法比較簡單點
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items .Add (DateTime .Now .ToString ()+"開始");
Action action = new Action( delegate
{
this.listBox1.BeginInvoke(new Action(async () =>
{
listBox1.Items.Add(await GetData1());
}));
});
action .BeginInvoke (null,null);
listBox1.Items.Add(DateTime .Now .ToString ()+"結束");
}
private async Task<string>GetData()
{
System.Net.Http.HttpClient http = new System.Net.Http.HttpClient();
var result = await http.GetAsync("https://www.google.com/");
return DateTime.Now.ToString() + result;
}