生活随笔
收集整理的這篇文章主要介紹了
利用TaskCompletionSource将EAP转换成TAP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
?
1.原始的異步方法的調用
?
我們來看個簡單的例子,在這里演示調用 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 綁在一起,維護起來會相當的痛苦。
?
2.將 EAP 轉換成 TAP步驟
?
- 命名規則以 Async 為后綴
- 返回 Task 或是 Task<TResult>
- 調用 TaskCompletionSource 方法
?
改變 Task 狀態可調用以下三個方法:SetCanceled、SetException、SetResult
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; ????} } ?
轉自:http://www.it165.net/pro/html/201308/6710.html
?
3.微軟的封裝
?
public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address) { ????// Create the task to be returned ????var tcs = new TaskCompletionSource<byte[]>(address); ????// Setup the callback event handler ????DownloadDataCompletedEventHandler handler = null; ????handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler); ????webClient.DownloadDataCompleted += handler; ????// Start the async work ????try ????{ ????????webClient.DownloadDataAsync(address, tcs); ????} ????catch(Exception exc) ????{ ????????// If something goes wrong kicking off the async work, ????????// unregister the callback and cancel the created task ????????webClient.DownloadDataCompleted -= handler; ????????tcs.TrySetException(exc); ????} ????// Return the task that represents the async operation ????return tcs.Task; } ?
internal class EAPCommon { ????internal static void HandleCompletion<T>( ????????TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler) ????{ ????????// Transfers the results from the AsyncCompletedEventArgs and getResult() to the ????????// TaskCompletionSource, but only AsyncCompletedEventArg's UserState matches the TCS ????????// (this check is important if the same WebClient is used for multiple, asynchronous ????????// operations concurrently). Also unregisters the handler to avoid a leak. ????????if (e.UserState == tcs) ????????{ ????????????if (e.Cancelled) tcs.TrySetCanceled(); ????????????else if (e.Error != null) tcs.TrySetException(e.Error); ????????????else tcs.TrySetResult(getResult()); ????????????unregisterHandler(); ????????} ????} }
轉載于:https://www.cnblogs.com/pengzhen/p/4831339.html
總結
以上是生活随笔為你收集整理的利用TaskCompletionSource将EAP转换成TAP的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。