【发布时间】:2016-04-09 03:18:05
【问题描述】:
我正在尝试遍历包含 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 指向运行专有 WebSphere MQ 服务的内部服务器。其要点是检查内部数据源,以查看我们是否与客户有关系。
我们每天在数百个站点的客户关系管理流程中运行相同的流程。所以我不认为有任何许可问题,并且我确信这些 MQ 服务可以接受每个客户端的多个调用。
编辑 2
更多研究表明 2 个连接限制是有效的。但是,使用 ServicePointManager 可能能够绕过此限制。我找不到将 ServicePointManager 与 HttpWebRequests 一起使用的 C# 示例。
谁能给我指出一个有效的资源或提供一个代码示例?
【问题讨论】:
-
很可能是接收 Web 服务器的限制,或者可能是许可限制,具体取决于您调用的实际 Web 服务。也可能是 IsNotACustomer 中的非线程安全代码,因此如果您验证 Web 服务器允许来自同一源计算机的 2 个以上同时连接,您可能需要发布该代码。
-
@MattJordan 请查看我的编辑,谢谢
-
WebSphere MQ 服务器上的 MAXINST 和 MAXINSTC 配置是什么? MAXINST 几乎可以肯定很高,因为您从数百个不同的站点访问它,但每个客户端的 MAXINSTC 仍然可能是一个问题。 ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.con.doc/…