我正在尝试创建一个web-scraper,它可以并行查询很多url并使用Task.WhenAll()等待他们的响应。但是,如果其中一个任务不成功,则WhenAll失败。我期待许多任务返回404并希望处理或忽略这些。例如:
string urls = Enumerable.Range(1, 1000).Select(i => "https://somewebsite.com/" + i));
List<Task<string>> tasks = new List<Task<string>>();
foreach (string url in urls)
{
tasks.Add(Task.Run(() => {
try
{
return (new HttpClient()).GetStringAsync(url);
}
catch (HttpRequestException)
{
return Task.FromResult<string>("");
}
}));
}
var responseStrings = await Task.WhenAll(tasks);
这永远不会遇到catch语句,并且WhenAll在第一个404失败。如何让WhenAll忽略异常并返回成功完成的任务?更好的是,它可以在下面的代码中的某处完成吗?
var tasks = Enumerable.Range(1, 1000).Select(i => (new HttpClient()).GetStringAsync("https://somewebsite.com/" + i))));
var responseStrings = await Task.WhenAll(tasks);
感谢您的帮助。
答案 0 :(得分:1)
您需要使用await
来观察异常:
var tasks = Enumerable.Range(1, 1000).Select(i => TryGetStringAsync("https://somewebsite.com/" + i));
var responseStrings = await Task.WhenAll(tasks);
var validResponses = responseStrings.Where(x => x != null);
private async Task TryGetStringAsync(string url)
{
try
{
return await httpClient.GetStringAsync(url);
}
catch (HttpRequestException)
{
return null;
}
}