Task.WhenAll中的任务的错误处理

时间:2017-04-07 16:56:29

标签: c# linq http asynchronous task

我正在尝试创建一个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);

感谢您的帮助。

1 个答案:

答案 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;
  }
}