zoukankan      html  css  js  c++  java
  • 利用TaskCompletionSource将EAP转换成TAP

     

     

    1.原始的异步方法的调用

     

    我们来看个简单的例子,在这里演示调用 WebClient.DownloadStringAsync 方法(这个方法不是 TAP),然后由 WebClient.DownloadStringCompleted 事件通知 UI 更新,这是大多数人都会用的方法。

     

    1. private void DownloadString(string address)
    2. {
    3.     WebClient wc = new WebClient();
    4.     wc.DownloadStringCompleted += (sender, e) =>
    5.     {
    6.         if (e.Cancelled)
    7.             this.textBox1.Text = "Cancel";
    8.         else if (e.Error != null)
    9.             this.textBox1.Text = "Error";
    10.         else
    11.             this.textBox1.Text = e.Result;
    12.     };
    13.  
    14.     wc.DownloadStringAsync(new Uri(address));
    15. }

    客户端调用

     

    1. private void button_DownloadString_Click(object sender, EventArgs e)
    2. {
    3.     DownloadString("https://www.google.com.tw/");
    4. }

    这是一个很简单的例子,一旦若项目里有成千上万的通知事件跟 UI 绑在一起,维护起来会相当的痛苦。

     

    2.将 EAP 转换成 TAP步骤

     

    • 命名规则以 Async 为后缀
    • 返回 Task 或是 Task<TResult>
    • 调用 TaskCompletionSource 方法

     

    改变 Task 状态可调用以下三个方法:SetCanceled、SetException、SetResult

    1. private Task<string> DownloadStringAsync(string address)
    2. {
    3.     var tcs = new TaskCompletionSource<string>();
    4.     WebClient wc = new WebClient();
    5.     wc.DownloadStringCompleted += (sender, e) =>
    6.     {
    7.         if (e.Cancelled)
    8.             tcs.SetCanceled();
    9.         else if (e.Error != null)
    10.             tcs.SetException(e.Error);
    11.         else
    12.             tcs.SetResult(e.Result);
    13.     };
    14.  
    15.     wc.DownloadStringAsync(new Uri(address));
    16.     return tcs.Task;
    17. }

     

    客户端调用

    1. private async void button_DownloadStringAsync_Click(object sender, EventArgs e)
    2. {
    3.     var task = DownloadStringAsync("https://www.google.com.tw/");
    4.     await task;
    5.     if (task.IsCanceled)
    6.     {
    7.         this.textBox1.Text = "Cancel";
    8.     }
    9.     else if (task.IsFaulted)
    10.     {
    11.         this.textBox1.Text = "Error";
    12.     }
    13.     else if (task.IsCompleted)
    14.     {
    15.         this.textBox1.Text = task.Result;
    16.     }
    17. }

     

    转自:http://www.it165.net/pro/html/201308/6710.html

     

    3.微软的封装

     

    1. public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address)
    2. {
    3.     // Create the task to be returned
    4.     var tcs = new TaskCompletionSource<byte[]>(address);
    5.  
    6.     // Setup the callback event handler
    7.     DownloadDataCompletedEventHandler handler = null;
    8.     handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
    9.     webClient.DownloadDataCompleted += handler;
    10.  
    11.     // Start the async work
    12.     try
    13.     {
    14.         webClient.DownloadDataAsync(address, tcs);
    15.     }
    16.     catch(Exception exc)
    17.     {
    18.         // If something goes wrong kicking off the async work,
    19.         // unregister the callback and cancel the created task
    20.         webClient.DownloadDataCompleted -= handler;
    21.         tcs.TrySetException(exc);
    22.     }
    23.  
    24.     // Return the task that represents the async operation
    25.     return tcs.Task;
    26. }

     

    1. internal class EAPCommon
    2. {
    3.     internal static void HandleCompletion<T>(
    4.         TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler)
    5.     {
    6.         // Transfers the results from the AsyncCompletedEventArgs and getResult() to the
    7.         // TaskCompletionSource, but only AsyncCompletedEventArg's UserState matches the TCS
    8.         // (this check is important if the same WebClient is used for multiple, asynchronous
    9.         // operations concurrently). Also unregisters the handler to avoid a leak.
    10.         if (e.UserState == tcs)
    11.         {
    12.             if (e.Cancelled) tcs.TrySetCanceled();
    13.             else if (e.Error != null) tcs.TrySetException(e.Error);
    14.             else tcs.TrySetResult(getResult());
    15.             unregisterHandler();
    16.         }
    17.     }
    18. }
  • 相关阅读:
    Android中Context具体解释 ---- 你所不知道的Context
    JDK6、Oracle11g、Weblogic10 For Linux64Bit安装部署说明
    matplotlib 可视化 —— 定制 matplotlib
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    指数函数的研究
    指数函数的研究
    指数分布的研究
  • 原文地址:https://www.cnblogs.com/pengzhen/p/4831339.html
Copyright © 2011-2022 走看看