1

我正忙着通过加载并行、同时调用来对我们的公共 API 进行性能测试。代码如下。

int batchSize = 10;

ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = batchSize;

Parallel.For(0, batchSize, parallelOptions, j =>
{
    Debug.WriteLine("Thread began at " + DateTime.Now.ToLongTimeString());

    using (WebClient client = new WebClient())
    {
        Stopwatch sw = Stopwatch.StartNew();
        byte[] arr = client.DownloadData("http://myapiurl/webservice.svc");
        sw.Stop();

        Console.WriteLine(sw.ElapsedMilliseconds.ToString());
    }
});

但我得到了奇怪的结果:

  • 从调试输出中,我可以看到所有线程都在完全相同的时间启动(如预期的那样)。

  • 我还记录了从 Web 服务中处理 API 调用所花费的时间(这存储在日志表中)。每个电话大约需要相同的时间……大约 2.5 秒。

  • 但现在控制台输出不相关。我希望它只比网络服务记录的时间长一点。输出:

2883 
2914 
5653 
5822 
8000 
8250 
10215 
10539 
11622 
12494

我可以提出以下可能的原因:

  • 就好像WebClient.DownloadData在自己的实例中排队我的请求一样。

  • IIS 正在排队我的网络请求。这是不可能的,因为没有其他东西可以访问 API。

4

1 回答 1

3

所有 HTTP 请求都由 ServicePointManager 管理,它管理与各种主机的连接池。每个主机的并发连接(以及 HTTP 请求)存在限制。这可以通过调用来增加:

ServicePointManager.FindServicePoint("http://myapiurl/webservice.svc")
    .ConnectionLimit = 100; //arbitrary value

还值得记住的是,HttpWebRequest(这是WebClient使用的)的 .Net 实现永远不会真正异步,因为 DNS 查找在异步发出请求之前同步发生。我一直认为这是一个完全延迟的设计决策,它阻止了高性能的 http 请求(尤其是在蜘蛛/爬行场景中)。

于 2013-09-25T12:57:49.123 回答