2009-09-24 80 views
3

我正在运行多线程的C#控制台应用程序。核心进程检索一些要处理的数据,将其分割成可配置数量的较小数据集,然后生成相同数量的线程来处理每个数据子集。多线程WebRequest调用和争用

要处理单个记录,线程必须使用WebRequest类和POST方法调用Web服务。查询与GetRequestStream()一起发送,并使用GetResponse()检索响应。

在伪代码,程序看起来是这样的:

prepare WebRequest data; 
* get time (start-of-Processing); 
Stream str = request.GetRequestStream(); 
Write data to stream; 
stream.Close(); 
WebResponse resp = request.GetResponse(); 
* get time (response-received); 
process response; 
finally close response stream; 

时序数据表明,当我们分裂我们的数据为超过4个线程,我们的吞吐量的过程作为一个整体没有改善,在某些情况下甚至会下降。来自Web服务的时间数据保持其性能不变。

  • 在4个线程,我们的表观开销 发送数据和检索围绕 第二所述 响应流的平均值。
  • 当我们运行4个以上的线程时, 的平均值上升,最大值为 遇到了几十秒!

今天我能够运行两个单独的进程,每个进程运行4个线程(但基本上确保每个线程仍在唯一数据上运行)。这一次,我们的整体吞吐量几乎翻了一番,每个过程都有稳定的时间约一秒。

这使我相信我们正在对WebRequest类的资源造成某种限制;但它是一个每个进程的限制,而不是一个机器限制。我知道我们可以使用BeginGetRequestStream和BeginGetResponse异步调用我们的调用,但是我怀疑如果我们实际上遇到某种资源限制,它会产生积极影响?!

我应该看看如何让单个流程中的拆分次数不会减少,从而降低性能?

+0

感谢您的细节。 – 2009-09-24 19:59:17

回答

13

您需要提高可以向单个主机发出的同时发出的Web请求的数量 - 否则,尽管CPU数量充足,但您的线程基本上仍会等待对方完成。要做到这一点,最简单的方法是使用的app.config<connectionManagement>元素:

<configuration> 
    <system.net> 
    <connectionManagement> 
     <add address = "*" maxconnection = "100" /> 
    </connectionManagement> 
    </system.net> 
</configuration> 
+0

感谢乔恩 - 这听起来很有希望......一旦我有机会测试这将是明天:)我会给更多反馈:) – Nij 2009-09-24 21:53:30

+0

谢谢你谢谢你谢谢你约翰!这个配置不仅可以改变我正在运行的线程数量,而且还可以减少“一秒钟”的开销 - 所以我必须已经获得了相当多的争论。 – Nij 2009-09-25 08:55:10

+0

https://support.microsoft。com/en-us/kb/821268此Microsoft知识库建议将12 *个处理器数作为值,但还列出了与ASP .Net线程池一起与传出异步调用的性能直接相关的其他配置值。 – Mazrick 2015-04-23 21:27:40

0

多少个处理器/核心不在于你正在运行此计算机上有哪些?

当您调度的线程多于系统中的核心时,调度程序必须对每个线程进行时间片化并安排它们在可用核心上运行。所以,除非你的流程中有死亡时间,否则性能不会增加,实际上可能会下降 - 这就是你所描述的。

+0

如果Web请求每个都花费大约一秒钟的时间,那听起来应用程序与CPU绑定的距离非常远 - 并且当有两个进程确认时,它的运行速度会快两倍。 – 2009-09-24 19:58:18

+0

我想这是有道理的..我的推理是,因为他说4个线程工作正常,但任何东西都会降低性能,而且由于四核心非常受欢迎,这似乎是造成这种麻烦的一个可能原因。但是我越想越没有意义.. – 2009-09-24 20:03:08

+0

我们即将转向四核,但它是在双核上,我们确实发现了4个请求的“限制”。在这个过程中,CPU的运行速度大约为1-2%,网络也是如此(根据任务管理器),所以这些都不是问题。 – Nij 2009-09-24 21:55:21