. 简介:
基于事件的异步编程模式(EAP)是.NET Framework 2.0 中引入的一种编程模式,是一种异步编程的方式,与.NET中的APM(异步编程模型)和TPL(任务并行库)不同,入口点不是Beginxxx和Endxxx方法或Task的异步方法,而是定义了异步方法并触发事件来通知异步操作完成。异步执行单元采用回调函数注册的方式,通过在异步操作完成时触发事件来通知应用程序。EAP的实现是基于.NetDelegate类型,该类型定义了一系列委托和异步操作的钩子事件(异步事件单元中事件的供应商)。EAP中最重要的概念是两个AsynXXX方法,它们分别触发了异步操作的开始和结束(异步事件单元中事件的消费者)。在这个模式中,执行异步操作的类是一种称为XXxCompletedEventArgs 的类型,该类型在构造函数中封装了异步操作的结果。
. EAP的步骤:
- 为异步操作定义方法以及事件。该操作负责引发已定义的事件以通知应用程序异步操作的状态。
例如,下面示例中是使用WebClient.DownloadFileAsync()异步方式下载文件,为异步操作定义回调函数,并定义完成事件和回调函数:
public static void Main(){
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted +=
new AsyncCompletedEventHandler( DownloadFileCallback );
Uri uri = new Uri("http://www.xxx.com/xx.jpg");
webClient.DownloadFileAsync(uri, @".\xx.jpg");
}
private static void DownloadFileCallback(Object sender, AsyncCompletedEventArgs e){
Console.WriteLine("Download complete");
}
在示例中,WebClient.DownloadFileCompleted 事件表示异步操作的完成。然后使用AsyncCompletedEventHandler 事件处理程序类型向Completed事件添加DownloadFileCallback方法。在异步操作完成时,使用DownloadFileCallback实例作为回调函数。
- 启动异步任务。在下面的示例中,使用WebClient.DownloadFileAsync()方法启动异步任务:
Uri uri = new Uri("http://www.xxx.com/xx.jpg");
webClient.DownloadFileAsync(uri, @".\xx.jpg");
在异步任务完成后返回结果以及提供状态或其他信息时调用回调函数。
- 在回调函数中检索结果
在异步操作完成后,会异步触发回调函数,可以从回调函数获取异步操作的结果。例如,在DownloadFileCallback示例中:
```csharp
private static void DownloadFileCallback(Object sender, AsyncCompletedEventArgs e){
if (e.Cancelled == true)
{
Console.WriteLine("Download has been canceled. result is {0}",
e.Cancelled);
}
else{
Console.WriteLine("Download complete");
}
}
使用`AsyncCompletedEventArgs`,在回调函数中检索是否已取消异步操作,并可获取异步操作的结果。
#. EAP的优点:
- 写出的代码非常清晰,避免了APM的复杂性以及TPL的混乱性。
- 使用更加公用的事件委托为异步方法添加了重载方法,使得代码更具有可读性和可维护性。
#. 示例一:
下面是一个简单的控制台程序,下载CSDN博客文章,并使用EAP来提供异步响应:
```csharp
using System;
using System.Net;
using System.IO;
class Program
{
static void Main(string[] args)
{
string url = "https://blog.csdn.net/q1005206184/article/details/104502634";
string filename = "csdn.html";
DownloadFile(url, filename);
Console.WriteLine("download started...");
Console.ReadLine();
}
static void DownloadFile(string url, string filename)
{
WebClient client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged);
client.DownloadFileAsync(new Uri(url), filename);
}
static void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
Console.WriteLine("download complete...");
}
static void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine("downloading... {0}% complete", e.ProgressPercentage);
}
}
在上面的示例中,Create方法以异步方式下载指定的文件,并使用DownloadFileCompleted回调函数来通知该操作已经完成。另外,使用DownloadProgressChanged事件来在控制台窗口中显示下载进度。最后,在Main方法中调用DownloadFile方法。
. 示例二:
下面是另一个示例用于演示基于事件的异步编程模式(EAP)。
using System;
using System.ComponentModel;
using System.Net;
public class Example
{
static void Main()
{
Console.WriteLine("Starting the download.\n");
SingleDownload();
Console.ReadLine();
}
public static void SingleDownload()
{
// Download the default URL to a temporary file.
WebClient client = new WebClient();
Uri uri = new Uri("http://www.contoso.com/library/homepage/images/homepage4.jpg");
// Specify that the DownloadFileCallback method gets called when the download completes.
client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
// Specify a progress notification handler.
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
client.DownloadFileAsync(uri, "Tempfile.jpg");
}
private static void DownloadFileCallback(object sender, AsyncCompletedEventArgs e)
{
// Process the downloaded file
Console.WriteLine("The download complete.");
}
private static void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine("{0} percent download complete.", e.ProgressPercentage);
}
}
在上面的示例中,使用了WebClient.DownloadFileAsync来异步下载一个图像文件,每当下载进度发生变化时,DownloadProgressChanged事件处理方法将调用,以更新进度。在完成后,DownloadFileCallback方法将处理已下载文件。最后,在Main方法中调用SingleDownload方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET2.0版本中基于事件的异步编程模式(EAP) - Python技术站