提高.NET中多线程HttpWebRequests的性能

时间:2008-12-23 13:50:07

标签: c# .net multithreading httpwebrequest

我正在尝试衡量网络服务的吞吐量。

为了做到这一点,我编写了一个小工具,可以连续发送请求并从多个线程中读取响应。

每个线程的内部循环的内容如下所示:

public void PerformRequest()
{
  WebRequest webRequest = WebRequest.Create(_uri);

  webRequest.ContentType = "application/ocsp-request";
  webRequest.Method = "POST";
  webRequest.Credentials = _credentials;
  webRequest.ContentLength = _request.Length;
  ((HttpWebRequest)webRequest).KeepAlive = false;

  using (Stream st = webRequest.GetRequestStream())
    st.Write(_request, 0, _request.Length);

  using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
  using (Stream responseStream = httpWebResponse.GetResponseStream())
  using (BufferedStream bufferedStream = new BufferedStream(responseStream))
  using (BinaryReader reader = new BinaryReader(bufferedStream))
  {
    if (httpWebResponse.StatusCode != HttpStatusCode.OK)
      throw new WebException("Got response status code: " + httpWebResponse.StatusCode);

    byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
    httpWebResponse.Close();
  }      
}

似乎工作正常,除了某些东西似乎限制了这个工具。如果我使用每40个线程运行该工具的两个实例,那么我获得的吞吐量明显高于具有80个线程的一个实例。

我找到了ServicePointManager.DefaultConnectionLimit属性,我设置为10000(如果我通过app.config as suggested by Jader Dias设置它没有区别。)

在.NET或我的机器上是否有任何其他可能影响性能的设置? (我正在运行Vista,但我在Windows Server 2003上看到了同样的问题)。

或许对单个进程可以建立多少连接有一些限制?

6 个答案:

答案 0 :(得分:37)

您必须在app.config或web.config文件中设置maxconnection参数:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="80"/>
    </connectionManagement>
  </system.net>
</configuration>

在Windows XP中,高达100的值可以很好地工作。

更新:我刚刚发现上面的方法是另一种设置System.Net.ServicePointManager.DefaultConnectionLimit的方法

答案 1 :(得分:2)

答案 2 :(得分:2)

您是否尝试过增加网络设置中的最大连接数?

http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

答案 3 :(得分:1)

请记住,多线程代码总是会导致对任何共享资源的争用,即使您没有明确地共享任何可能正在使用共享资源的类的内容。

如果你真的用2 40个线程exes而不是1 80个线程exe获得更好的性能,那么你需要用共享资源开始调查。如果是这种情况,您引用的代码远没有创建和管理线程的代码那么有趣。

我要抛弃的另一件事是,你可以获得一些工具,这些工具一般会为你做这类事。见http://support.microsoft.com/kb/231282。 Visual Studio中也包含(我不确定是什么skus)是新一代Web应用程序性能测试工具。我相信如果你看起来你也可以找到一些非MS的东西。

答案 4 :(得分:0)

w.r.t表现有两个重要方面:

  1. 一方面是所有人建议的,客户端使用数量的TCP连接 (通常更好,如果这些连接被持久化(keep alive = true)),请参阅:http://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionlimit(v=vs.110).aspxHow and where the TCP connection has been created in httpwebrequest, and how is it related to servicepoint?Why System.Net.ServicePoint.ConnectionLimit uses '7FFFFFFF' (Int32.MaxValue/2147483647) when a client connects to a service on 'localhost'?System.Net.ServicePointManager.DefaultConnectionLimit and .MaxServicePointIdleTime

  2. 第二个方面不是使用多个新线程/或使用工作线程在代码片段中使用同步调用(如httpwebrequest.getrequeststream)并行工作,完全拥抱异步模型 (例如,开始/结束请求流或新任务变体)。这样CPU总是很忙,让I / O完成端口线程只需通过调用回调在工作线程池线程中发送响应。 (您可以参考:How does .NET make use of IO Threads or IO Completion Ports?http://blog.marcgravell.com/2009/02/async-without-pain.htmlHttpWebRequest and I/O completion ports

  3. 的问候。

答案 5 :(得分:-1)

你是如何创建线程的?我假设你知道你有80个线程,你没有使用线程池管理器,因为使用线程池管理器你可以要求尽可能多的线程,你一次只能获得25个活动线程。如果使用数组手动创建线程,那么实际上您将获得所需数量,但是它们仍然位于相同的进程空间中,因此可能会限制它们在单独进程中运行的线程。

您还可以查看线程创建的公寓样式,我相信Thread类ctor默认使用STA。尝试使用MTA,看看它们是否会影响性能。