我想提高程序的性能,向同一外部API端点发出多个HTTP请求。因此,我创建了一个控制台应用程序来执行一些测试。方法GetPostAsync
向外部API发送异步HTTP请求,并以字符串形式返回结果。
private static async Task<string> GetPostAsync(int id)
{
var client = new HttpClient();
var response = await client.GetAsync($"https://jsonplaceholder.typicode.com/posts/{id}");
return await response.Content.ReadAsStringAsync();
}
此外,我还实现了以下方法,以测试执行时间最短的方法。
private static async Task TaskWhenAll(IEnumerable<int> postIds)
{
var tasks = postIds.Select(GetPostAsync);
await Task.WhenAll(tasks);
}
private static async Task MultipleAwait(IEnumerable<int> postIds)
{
foreach (var postId in postIds)
{
await GetPostAsync(postId);
}
}
使用集成的Stopwatch
类,我测量了这两种方法的执行时间,有趣的是,使用Task.WhenAll
的方法比其他方法的效果更好:
发出50个HTTP请求
- TaskWhenAll:〜650ms
- MultipleAwait:〜4500ms
为什么使用Task.WhenAll
的方法如此之快,并且在选择这种方法时会产生负面影响(例如,异常处理等)?
答案 0 :(得分:5)
为什么使用
Task.WhenAll
的方法这么快
速度更快,因为您不等待GetPostAsync
。因此,实际上,每次您await client.GetAsync($"https://jsonplaceholder.typicode.com/posts/{id}");
控件都会返回给调用方,然后调用方可以发出另一个HTTP请求。如果您认为HTTP请求比创建新客户端长得多,则可以通过并行运行多个HTTP请求来有效地具有并行性。 WhenAll
只会创建一个悬浮点,并等待所有任务完成。
使用多次等待方法,您可以从await GetPostAsync(postId)
循环通过foreach
依次发出HTTP请求。您开始执行任务,但与此同时,您创建了一个挂起点并等待其完成。
在以下情况下是否有任何负面影响(即异常处理等) 选择这种方法而不是其他方法?
使用await/async
模式处理异常不会产生负面影响,就像通常使用try-catch
块一样。 WhenAll
将汇总处于Faulted
状态的每个任务的所有异常。