在过去,我使用迭代器方法实现了这一点:每次您想要请求另一个URL时,都使用“yield return”将控制权传递回主程序。一旦请求完成,主程序就会调用您的迭代器来执行下一个工作。
您可以有效地使用C编译器为您编写状态机。其优点是,您可以在迭代器方法中编写看起来正常的C代码来驱动整个过程。
using System;
using System.Collections.Generic;
using System.Net;
class Program
{
static void onEx(Exception ex) {
Console.WriteLine(ex.ToString());
}
static IEnumerable<Uri> Downloader(Func<DownloadDataCompletedEventArgs> getLastResult) {
Uri url1 = new Uri(Console.ReadLine());
Uri url2 = new Uri(Console.ReadLine());
string someData = Console.ReadLine();
yield return url1;
DownloadDataCompletedEventArgs res1 = getLastResult();
yield return new Uri(url2.ToString() + "?data=" + res1.Result);
DownloadDataCompletedEventArgs res2 = getLastResult();
Console.WriteLine(someData + res2.Result);
}
static void StartNextRequest(WebClient webThingy, IEnumerator<Uri> enumerator) {
if (enumerator.MoveNext()) {
Uri uri = enumerator.Current;
try {
Console.WriteLine("Requesting {0}", uri);
webThingy.DownloadDataAsync(uri);
} catch (Exception ex) { onEx(ex); }
}
else
Console.WriteLine("Finished");
}
static void Main() {
DownloadDataCompletedEventArgs lastResult = null;
Func<DownloadDataCompletedEventArgs> getLastResult = delegate { return lastResult; };
IEnumerable<Uri> enumerable = Downloader(getLastResult);
using (IEnumerator<Uri> enumerator = enumerable.GetEnumerator())
{
WebClient webThingy = new WebClient();
webThingy.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error == null) {
lastResult = e;
StartNextRequest(webThingy, enumerator);
}
else
onEx(e.Error);
};
StartNextRequest(webThingy, enumerator);
}
Console.WriteLine("Keeping process alive");
Console.ReadLine();
}
}