为什么在多次调用HttpClient.GetStringAsync()时等待一次只要等待每次调用?

时间:2015-11-01 13:55:02

标签: c# asynchronous

using System.Net.Http;  
using Microsoft.VisualStudio.TestTools.UnitTesting;  
using System.Threading.Tasks;  
using System.Diagnostics;  

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public async Task ExceuteMultipleRequestsInParallel()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start(); 
        HttpClient client = new HttpClient();
        Task<string> ms = client.GetStringAsync("http://www.microsoft.com");
        Task<string> msdn = client.GetStringAsync("http://msdn.microsoft.com");
        Task<string> blogs = client.GetStringAsync("http://blogs.msdn.com");
        await Task.WhenAll(ms, msdn, blogs);
        sw.Stop();
        var result = sw.Elapsed.ToString();
    }

    [TestMethod]
    public async Task ExcecuteMultipleRequests()
    {
        Stopwatch sw = new Stopwatch();
        HttpClient client = new HttpClient();
        string ms = await client.GetStringAsync("http://www.microsoft.com");
        string msdn = await client.GetStringAsync("http://msdn.microsoft.com");
        string blogs = await client.GetStringAsync("http://blogs.msdn.com");
        sw.Stop();
        var result = sw.Elapsed.ToString();
    }
}

起初我只使用了一个HttpClient。我的期望是一个await Task.WhenAll(...)将占用最长任务所需的时间。我的期望是,这将比等待三个任务中的每一个都要少得多。

然而,事实似乎并非如此。此外,我总是不得不评论一个,否则缓存会扭曲事情。

然后我使用了三个HttpClients,令人惊讶的是,使用三次等待的方法花费的时间少于使用await Task.WhenAll(...)的方法。这看起来很奇怪。

有人请解释为什么我在第一个场景中使用WhenAll()并且在第二个场景中调用单个HttpClient时没有看到相同的经过时间的改进(就像我在第二个场景中那样)(调用三个{ {1}}每个实例一次)?

HttpClient

1 个答案:

答案 0 :(得分:0)

你描述的行为对我来说听起来很正常。我认为没有理由期望单个HttpClient实例在任何给定时间处理多个HTTP操作。

因此,当您使用单个HttpClient实例时,如果在第一次调用完成之前再次调用GetStringAsync(),则该类别无选择,只需简单地对操作进行排队,而不是启动该操作直到前一个已完成。同样是第三次操作。

当您使用三个不同的实例时,每个实例都可以独立进行,因此所有三个请求可以同时发生。

同时等待所有三个操作(即调用WhenAll())的事实不能也不会改变HttpClient内部实际执行它们的顺序。 HttpClient能够为您提供三个不同的任务,等待它们不会改变自身的单个实例一次只能处理一个事实的事实。并且由于上一次操作甚至无法启动,直到所有先前排队的操作都已完成,您将获得相同的基本已用时间,就好像您只是等待每个操作依次完成,然后自己将下一个操作排入队列。