并行ForEach在调用Exteranl服务时仅限于两个核心

时间:2016-04-08 16:21:48

标签: c# task-parallel-library

我正在尝试迭代20,000多条客户记录。我正在使用Parallel.ForEach()循环来尝试加速处理。在委托函数中,我正在对外部Web服务进行HTTP POST以验证客户信息。在这样做时,循环限制为2个线程或逻辑核心。如果我尝试增加并行度,则进程会抛出错误"底层连接已关闭:服务器已关闭预期保持活动状态的连接"

使用外部进程或接收Web服务器的限制时,这是循环的默认行为吗?

我的代码非常简单:

Parallel.ForEach ( customerlist, new ParallelOptions {MaxDegreeOfParallelism = 3 },( currentCustomer ) =>
{
    if ( IsNotACustomer ( currentCustomer.TIN ) == true ) <--IsNotCustomer is where the HTTP POST takes place
    {
        ...Write data to flat file...
    }
});

如果我将MaxDegreesOfParallelism更改为2,则循环运行正常。

此代码大约需要80分钟才能流失20,000条记录。虽然这不是不可接受的,如果我可以通过增加线程数来缩短时间,那就更好了。

完整异常消息(没有堆栈跟踪):

  

System.Net.WebException:底层连接已关闭:A   预计将保持活着的连接被关闭   服务器

     

在System.Net.HttpWebRequest.GetResponse()

非常感谢任何协助。

  

修改

HTTP POST代码是:

HttpWebRequest request = ( HttpWebRequest )WebRequest.Create ( AppConfig.ESLBridgeURL + action );
request.Method = "POST";
request.GetRequestStream ( ).Write ( Encoding.UTF8.GetBytes ( body ), 0, body.Length );

Stream stream = request.GetResponse ( ).GetResponseStream ( );
StreamReader reader = new StreamReader ( stream );

output = reader.ReadToEnd ( );

URL是运行专有Web Sphere MQ服务的内部服务器。其要点是检查内部数据源,看看我们是否与客户建立了关系。

我们在每天数百个站点的客户关系管理流程中运行相同的流程。所以我不相信存在任何许可问题,我确信这些MQ服务可以接受每个客户端的多个调用。

  

编辑2

更多的研究表明2连接限制是有效的。但是,使用ServicePointManager可能会绕过此限制。我找不到的是使用ServicePointManager和HttpWebRequests的C#示例。

有人能指出我有效的资源或提供代码示例吗?

2 个答案:

答案 0 :(得分:1)

您可能正在运行默认的2个客户端限制。请参阅System.Net.ServicePointManager.DefaultConnectionLimit on MSDN

  

ServicePoint对象允许的最大并发连接数。默认值为2.

可能相关的问题:How Can I programmatically remove the 2 connection limit in WebClient?

答案 1 :(得分:0)

谢谢Matt Stephenson和Matt Jordan指出我正确的方向。

我找到了一个解决方案,将我的处理工作减少了一半。我会继续调整以获得最佳效果,但这就是我所得到的。

我将以下内容添加到应用程序配置文件中:

.html('<html here/>')

然后我想出了如何使用ServicePointManager并设置以下内容:

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

对于我的开发机器,处理器计数为8。

这段代码允许我在大约45分钟内处理我的20,000多条记录(给予或接受)。