以下是我用来从多个网址检索数据的代码。对于几个网址,我得到了例外,但对于其他所有网址,我都获得了有效的数据。问题是,对于下面的apporoach,我无法收集能够无任何问题地检索数据的线程的数据。反正收集尽可能多的url响应,同时还知道哪些url会抛出异常?
static void Main(string[] args)
{
var URLsToProcess = new List<string>
{
"http://www.microsoft.com",
"http://www.stackoverflow.com",
"http://www.google.com",
"http://www.apple.com",
"http://www.ebay.com",
"http://www.oracle.com",
"http://www.gmail.com",
"http://www.amazon.com",
"http://www.outlook.com",
"http://www.yahoo.com",
"http://www.amazon124.com",
"http://www.msn.com"
};
string[] tURLs = null;
try
{
tURLs = URLsToProcess
.AsParallel()
.WithDegreeOfParallelism(3)
.Select(uri => DownloadStringAsTask(new Uri(uri)).Result)
.ToArray();
}
catch (AggregateException ex)
{
AggregateException exf = ex.Flatten();
}
Console.WriteLine("download all done");
if (tURLs != null)
{
foreach (string t in tURLs)
{
Console.WriteLine(t);
}
}
}
static Task<string> DownloadStringAsTask(Uri address)
{
TaskCompletionSource<string> tcs =
new TaskCompletionSource<string>();
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
if (args.Error != null)
tcs.SetException(args.Error);
else if (args.Cancelled)
tcs.SetCanceled();
else
tcs.SetResult(args.Result);
};
client.DownloadStringAsync(address);
return tcs.Task;
}
答案 0 :(得分:2)
是的,有:
var tasks = URLsToProcess.Select(uri => DownloadStringAsTask(new Uri(uri))).ToArray();
while (tasks.Any())
{
try
{
Task.WaitAll(tasks);
break;
}
catch (Exception e)
{
// handle exception/report progress...
tasks = tasks.Where(t => t.Status != TaskStatus.Faulted).ToArray();
}
}
var results = tasks.Select(t => t.Result);
使用Task.WaitAll
等待(同步,因为async-await
不可用)同时完成所有任务。如果Task.WaitAll
成功完成,请跳出while
循环并使用Task.Result
提取结果。如果有异常,请删除故障任务并再次等待其他任务,等等。