在可能的情况下在获取数据的同时处理异常
本文关键字:处理 异常 获取 情况下 数据 | 更新日期: 2023-09-27 18:35:43
下面是我用来从多个URL检索数据的代码。对于几个网址,我得到例外,但对于所有其他网址,我确实得到了有效的数据。问题是,使用下面的apporoach,我无法为能够毫无问题地检索数据的线程收集数据。无论如何,在知道哪些网址引发异常的同时收集尽可能多的 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;
}
是的,有:
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
提取结果。如果出现异常,请删除出错的任务,然后再次等待其他任务,依此类推。