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. }

利用TaskCompletionSource将EAP转换成TAP的更多相关文章

  1. ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100)

    原文:ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100) 对于非地理专业的开发人员,对与这些生涩的概念,我们不一定都要了解,但是我们要理解,凡是 ...

  2. 利用jpedal进行pdf转换成jpeg,jpg,png,tiff,tif等格式的图片

    项目中运用到pdf文件转换成image图片,开始时使用pdfbox开源库进行图片转换,但是转换出来的文件中含有部分乱码的情况.下面是pdfBox 的pdf转换图片的代码示例. try{ String ...

  3. 利用pdf2swf将PDF转换成SWF

    将PDF转换成SWF可以使用SWFTools工具中的pdf2swf(http://www.swftools.org/),CSDN快速免积分下载地址http://download.csdn.net/de ...

  4. 利用NPOI将EXCEL转换成HTML的C#实现

    领导说想做一个网页打印功能,而且模板可以自定义,我考虑了三个方案,一是打印插件,二是在线 html 编辑器,三是 excel 模板,领导建议用的是打印插件的形式,我研究了一下,一个是需要下载安装,二个 ...

  5. 转:ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100)

    对于非地理专业的开发人员,对与这些生涩的概念,我们不一定都要了解,但是我们要理解,凡是以经纬度为单位的都是地理坐标系,因为它归根结底是一个椭球体,只不过各个国家为了反映该国家所在区域地球的真实形状,而 ...

  6. 【Spring Boot】Spring Boot之利用Logstash将日志转换成以JSON的格式存储和输出

    一.Logstash的作用 Logstash是一个完全开源的工具,它可以对日志进行收集.过滤,能非常方便地将日志转换成以JSON的格式存储和输出,并将其存储供以后使用. 二.整合Logstash的步骤 ...

  7. 利用PHP将图片转换成base64编码的实现方法

    先来说一下为什么我们要对图片base64编码 base64是当前网络上最为常见的传输8Bit字节代码的编码方式其中之一.base64主要不是加密,它主要的用途是把某些二进制数转成普通字符用于网络传输. ...

  8. 利用反射将Datatable、SqlDataReader转换成List模型

    1. DataTable转IList public class DataTableToList<T>whereT :new() { ///<summary> ///利用反射将D ...

  9. Java 里把 InputStream 转换成 String 的几种方法

    我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量. 未真正关注这个问题之 ...

随机推荐

  1. Java 回调机制的理解

    // 在接口中声明一个处理耗时操作结果的回调方法. // Local 实现这个接口,实现处理耗时操作结果的回调方法. // Local 获得 Remote 对象,在子线程中调用 Remote 的处理耗 ...

  2. java 接口与继承

    一.继承条件下的构造方法调用 运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构 ...

  3. 在线预览Office文件【效果类似百度文库】(转载)

    转载地址:http://www.cnblogs.com/sword-successful/p/4031823.html 引言 结合上个项目和目前做的这个项目,其中都用到了Office文件在线预览,目前 ...

  4. 【翻译一】java-并发

    Lesson: Concurrency Computer users take it for granted that their systems can do more than one thing ...

  5. eclipse基础及开发插件

    Eclipse:http://www.eclipse.org/downloads/ Compare Package:http://www.eclipse.org/downloads/packages/ ...

  6. C# Qrcode生成二维码支持中文,带图片,带文字 2015-01-22 15:11 616人阅读 评论(1) 收藏

    1.下载Qrcode库源码,下载地址:http://www.codeproject.com/Articles/20574/Open-Source-QRCode-Library 2.打开源码时,部分类库 ...

  7. js中ascii码的转换

    今天在把原来用C写的程序移植到javascript上,但是有个地方一直调不通,后来才发现是js奇葩的字符处理出的问题.c中使用的字符处理比如加上一个字符值强制转换一下,在js中就行不通了. 但是js提 ...

  8. office excel 装Visual Studio后报错解决方案

    安装完vs后,vs会向office安装COM加载项,但是在启动Excel时会发生弹出此加载项安装出错的消息,如下图. 名称: 从: file:///D:/Program Files (x86)/Mic ...

  9. 10 个学习iOS开发的最佳网站(转)

    10 个学习iOS开发的最佳网站 作者 jopen 2012-09-26 08:59:56 1) Apple Learning Objective C Objective-C,通常写作ObjC和较少用 ...

  10. poj 1816 (Trie + dfs)

    题目链接:http://poj.org/problem?id=1816 思路:建好一颗Trie树,由于给定的模式串可能会重复,在原来定义的结构体中需要增加一个vector用来记录那些以该节点为结尾的字 ...