一些API,如WebClient,使用Event-based Async pattern。虽然这看起来很简单,并且可能在松散耦合的应用程序(例如,UI中的BackgroundWorker)中运行良好,但它并没有很好地链接在一起。C#中基于事件的异步;任何泛型重构可能?
例如,这是一个多线程程序,所以异步工作不会阻止。 (想象一下,这是在一个服务器应用程序中进行的,并且调用了数百次 - 你不想阻塞你的ThreadPool线程。)我们得到3个局部变量(“状态”),然后进行2次异步调用,结果是首先进入第二个请求(所以它们不能平行)。状态也可能发生变化(易于添加)。
使用Web客户端,事情最终会像下面(或者你最终创造了一堆的对象要像闭包):
using System;
using System.Net;
class Program
{
static void onEx(Exception ex) {
Console.WriteLine(ex.ToString());
}
static void Main() {
var url1 = new Uri(Console.ReadLine());
var url2 = new Uri(Console.ReadLine());
var someData = Console.ReadLine();
var webThingy = new WebClient();
DownloadDataCompletedEventHandler first = null;
webThingy.DownloadDataCompleted += first = (o, res1) => {
if (res1.Error != null) {
onEx(res1.Error);
return;
}
webThingy.DownloadDataCompleted -= first;
webThingy.DownloadDataCompleted += (o2, res2) => {
if (res2.Error != null) {
onEx(res2.Error);
return;
}
try {
Console.WriteLine(someData + res2.Result);
} catch (Exception ex) { onEx(ex); }
};
try {
webThingy.DownloadDataAsync(new Uri(url2.ToString() + "?data=" + res1.Result));
} catch (Exception ex) { onEx(ex); }
};
try {
webThingy.DownloadDataAsync(url1);
} catch (Exception ex) { onEx(ex); }
Console.WriteLine("Keeping process alive");
Console.ReadLine();
}
}
有没有重构这一事件的通用方式基于异步模式? (也就是说,不必为每个这样的API编写详细的扩展方法?)BeginXXX和EndXXX使它变得简单,但这种事件方式似乎没有提供任何方式。
对安东的答案进行详细说明。术语“异步工作流程”是您搜索的内容,请参阅http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx – 2009-03-13 17:13:35