异步编程模式(六):基于事件的异步调用模式
2012-02-01 15:06
239 查看
前一个日记介绍了以 WebResponse 为代表的支持IAsyncResult 异步调用模式的组件,.NET基类库中有部分组件实现 了另一种异步模式,
这就是"基于事件的异步模式(EAP模式)"。
实现 了EAP模式的最典型组件是WebClient。
WebClient定义了以下两个同步方法用于从WEB上下载文件:
为了实现异步调用,WebClient又定义了另两个对应的异步方法:
EAP规定方法名以 Async 结尾的方法是异步调用方法。
上面的方法,最后一个userToken参数前面已经说明了其作用。
其实很简单,当应用程序多次调用DownloadFileAsync方法的这个重载形式启动多个异步下载任务时,这个参数用于区分这些任务。简单地说,userToken
是异步下载任务的标识。为每个正在执行的下载任务给出唯一的标识,是程序员的责任。
为了让用户中途取消任务,WebClient定义了以下方法:
public void CancelAsync();
由于任务可以被取消,因此问题产生了:异步调用方法启动以后,调用者如何知道任务是正常结束还是被中途取消的?
答案很简单:异步调用任务结束时,实现 了EAP的组件会激发一个相应的事件。以WebClient为例,当DownloadFileAsync方法启动的异步下载任务结束时,它会激发以下事件:
public event AsyncCompletedEventHandler DownloadFileCompleted;
这一事件有一个 AsyncCompletedEventArgs 类型的参数,其中包含了重要的信息:
由此可见,只需在 DownloadFileCompleted事件的响应方法中检查一下事件参数的Cancelled属性,如果其值等于 true,就知道任务被中途取消了。
如果error属性不为null,则任务执行过程中一定引发了异常。上述两个条件都不满足时,则任务是顺利完成的。
当异步任务可能要执行很长时间时,往往需要通知用户当前工作完成的进度,为此,WebClient定义了以下事件:
public event DownloadProgressChangedEventHandler DownloadProgressChanged;
这个事件的参数中(DownloadProgressChangedEventArgs类型的对象)中包含了重要的信息。
1. TotalBytesToReceive:要传送的总字节数。
2. BytesReceived:已接收的字节数。
3.ProgressPercentage:工作完成的百分比。
掌握了以上知识,使用WebClient组件下载文件就变得非常简单,以下是一个代码框架:
下载完成事件响应代码框架如下:
下载进度事件响应代码框架如下:
依据前面的内容,我们可以对EAP形成以下的认识:
1.实现了EAP的组件定义 了以 Async 结尾的异步调用方法。
2.当异步调用任务结束时,会激发一个相应的事件,事件的参数包含重要的信息。
3.实现 了EAP的组件可能会提供一个用于取消异步任务的方法。
4.实现 了EAP的组件提供一个向用户报告进度的事件。
这就是"基于事件的异步模式(EAP模式)"。
实现 了EAP模式的最典型组件是WebClient。
WebClient定义了以下两个同步方法用于从WEB上下载文件:
public void DownloadFile(string address, string fileName); public void DownloadFile(Uri address, string fileName);
为了实现异步调用,WebClient又定义了另两个对应的异步方法:
public void DownloadFileAsync(Uri address, string fileName); public void DownloadFileAsync(Uri address, string fileName, object userToken);
EAP规定方法名以 Async 结尾的方法是异步调用方法。
上面的方法,最后一个userToken参数前面已经说明了其作用。
其实很简单,当应用程序多次调用DownloadFileAsync方法的这个重载形式启动多个异步下载任务时,这个参数用于区分这些任务。简单地说,userToken
是异步下载任务的标识。为每个正在执行的下载任务给出唯一的标识,是程序员的责任。
为了让用户中途取消任务,WebClient定义了以下方法:
public void CancelAsync();
由于任务可以被取消,因此问题产生了:异步调用方法启动以后,调用者如何知道任务是正常结束还是被中途取消的?
答案很简单:异步调用任务结束时,实现 了EAP的组件会激发一个相应的事件。以WebClient为例,当DownloadFileAsync方法启动的异步下载任务结束时,它会激发以下事件:
public event AsyncCompletedEventHandler DownloadFileCompleted;
这一事件有一个 AsyncCompletedEventArgs 类型的参数,其中包含了重要的信息:
public class AsyncCompletedEventArgs : EventArgs { public bool Cancelled { get; } //该值指示异步操作是否已被取消。 public Exception Error { get; }//该值指示异步操作期间发生的错误。 public object UserState { get; }//获取异步任务的唯一标识符,如果用户在启动本任务时设定了任务标识,则此属性值就是这个标识 }
由此可见,只需在 DownloadFileCompleted事件的响应方法中检查一下事件参数的Cancelled属性,如果其值等于 true,就知道任务被中途取消了。
如果error属性不为null,则任务执行过程中一定引发了异常。上述两个条件都不满足时,则任务是顺利完成的。
当异步任务可能要执行很长时间时,往往需要通知用户当前工作完成的进度,为此,WebClient定义了以下事件:
public event DownloadProgressChangedEventHandler DownloadProgressChanged;
这个事件的参数中(DownloadProgressChangedEventArgs类型的对象)中包含了重要的信息。
1. TotalBytesToReceive:要传送的总字节数。
2. BytesReceived:已接收的字节数。
3.ProgressPercentage:工作完成的百分比。
掌握了以上知识,使用WebClient组件下载文件就变得非常简单,以下是一个代码框架:
//从Web异步下载网址为FileAddress的文件 public void DownLoadFileFromWeb(string FileAddress) { WebClient client = new WebClient(); //挂接下载完成事件响应代码 client.DownloadFileCompleted += client_DownloadFileCompleted; //挂接下载进度事件响应代码 client.DownloadProgressChanged += client_DownloadProgressChanged; //启动异步下载文件任务 Uri uri = new Uri(FileAddress); client.DownloadStringAsync(uri); }
下载完成事件响应代码框架如下:
void client_DownloadFileCompleted(object sender,AsyncCompletedEventArgs e) { if(e.Cancelled) //用户取消了操作 { //处理代码。。。。 } if(e.Error != null) //有错误发生 { //处理代码 } if(e.UserState != null) //取出任务标识 { //处理代码 } //其它处理代码。。。 }
下载进度事件响应代码框架如下:
void client_DownloadProgressChanged(object sender,DownloadProgressChangedEventArgs e) { string info = "任务标识:{0},总数据:{1}字节,已下载:{2}字节,完成了{3}%。"; info = string.Format(info , e.UserState , e.TotalBytesToReceive , e.BytesReceived , e.ProgressPercentage); //..... }
依据前面的内容,我们可以对EAP形成以下的认识:
1.实现了EAP的组件定义 了以 Async 结尾的异步调用方法。
2.当异步调用任务结束时,会激发一个相应的事件,事件的参数包含重要的信息。
3.实现 了EAP的组件可能会提供一个用于取消异步任务的方法。
4.实现 了EAP的组件提供一个向用户报告进度的事件。
相关文章推荐
- 基于事件的异步调用模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- 实现基于事件的异步模式的最佳做法
- 基于事件的异步模式——01.backgroundWorker
- 演练:实现支持基于事件的异步模式的组件
- 确定何时实现基于事件的异步模式
- F#与ASP.NET(2):使用F#实现基于事件的异步模式
- 基于事件的异步模式——BackgroundWorker
- [你必须知道的异步编程]——基于任务的异步模式
- 异步编程:基于事件的异步编程模式(EMP)
- .NET中基于事件的异步模式-EAP
- 基于事件的异步模式——BackgroundWorker
- [你必须知道的异步编程]——基于任务的异步模式
- 基于事件的异步模式概述
- F#与ASP.NET(2):使用F#实现基于事件的异步模式
- 异步编程:基于事件的异步编程模式(EAP)