一些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