[C#.NET][TPL] 利用 TaskCompletionSource 將 EAP 轉換成 TAP
假使,類別裡面已經開發了 EAP(Event-based Asynchronous Pattern) 非同步模型,比較常用在 UI 的通知,對大都數的開發者會覺得它比 APM 好用許多,雖然大多數 FCL 的 EAP 底層是實作 APM 來的。
EAP 詳細建立方式可參考以下
http://www.dotblogs.com.tw/yc421206/archive/2012/10/25/78910.aspx
有關 TAP 非同步建立步驟可參考以下
http://www.dotblogs.com.tw/yc421206/archive/2013/08/05/113433.aspx
續上篇 http://www.dotblogs.com.tw/yc421206/archive/2012/10/25/78910.aspx,我們也可以透過 TPL 中的 TaskCompletionSource 將 EAP 轉換成 TAP,若你的專案有兩種非同步模型,選一種來轉換就好。
我們來看個簡單的例子,在這裡演示調用 WebClient.DownloadStringAsync 方法(這個方法不是 TAP),然後由 WebClient.DownloadStringCompleted 事件通知 UI 更新,這是大多數人都會用的方法。
private void DownloadString(string address)
{
WebClient wc = new WebClient();
wc.DownloadStringCompleted += (sender, e) =>
{
if (e.Cancelled)
this.textBox1.Text = "Cancel";
else if (e.Error != null)
this.textBox1.Text = "Error";
else
this.textBox1.Text = e.Result;
};
wc.DownloadStringAsync(new Uri(address));
}
用戶端調用
private void button_DownloadString_Click(object sender, EventArgs e)
{
DownloadString("https://www.google.com.tw/");
}
這是一個很簡單的例子,一旦若專案裡有成千上萬的通知事件跟 UI 綁在一起,維護起來會相當的痛苦。
將 EAP 轉換成 TAP步驟如下:
- 命名規則以 Async 為後綴
- 返回 Task 或是 Task<TResult>
- 調用 TaskCompletionSource 方法
改變 Task 狀態可調用以下三個方法
private Task<string> DownloadStringAsync(string address) { var tcs = new TaskCompletionSource<string>(); WebClient wc = new WebClient(); wc.DownloadStringCompleted += (sender, e) => { if (e.Cancelled) tcs.SetCanceled(); else if (e.Error != null) tcs.SetException(e.Error); else tcs.SetResult(e.Result); }; wc.DownloadStringAsync(new Uri(address)); return tcs.Task; }
用戶端調用
private async void button_DownloadStringAsync_Click(object sender, EventArgs e) { var task = DownloadStringAsync("https://www.google.com.tw/"); await task; if (task.IsCanceled) { this.textBox1.Text = "Cancel"; } else if (task.IsFaulted) { this.textBox1.Text = "Error"; } else if (task.IsCompleted) { this.textBox1.Text = task.Result; } }
結論:並非所有的 EAP 都可以透過本篇方法轉換,比如 SerialPort.DataReceived 事件
範例下載:https://dotblogsfile.blob.core.windows.net/user/yc421206/1308/20138711523887.zip
以上文章出自:http://www.dotblogs.com.tw/yc421206/archive/2013/08/07/113628.aspx
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET