我正忙于对我们的公共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。
答案 0 :(得分:3)
所有HTTP请求都由ServicePointManager审核,ServicePointManager管理与各种主机的连接池。每个主机的并发连接(以及HTTP请求)都有限制。通过调用以下内容可以增加这一点:
ServicePointManager.FindServicePoint("http://myapiurl/webservice.svc")
.ConnectionLimit = 100; //arbitrary value
还值得记住的是,HttpWebRequest的.Net实现(WebClient
使用的)永远不会真正异步,因为DNS查找是在异步发出请求之前同步发生的。我一直认为这是一个完全迟钝的设计决策,可以阻止高性能的http请求(特别是在蜘蛛网/抓取方案中)。