C# Linq AsParallel()是否可以过早地处理SoapHttpClientProtocol对象?

C# Linq AsParallel()是否可以过早地处理SoapHttpClientProtocol对象?,c#,asp.net-mvc-4,soap-client,plinq,arcgis-server,C#,Asp.net Mvc 4,Soap Client,Plinq,Arcgis Server,在我正在开发的ASP.NETMVC4Web应用程序中。我有一个页面,它基本上通过从SOAP服务获取数据来生成报告 我的代码基本上是这样的 List<CustomThings> serverInfos = ServerInfos; serverInfos.AsParallel().ForAll(srvInfo => { SoapHttpClientProtocol soapProxy = CreateProxy(srvInfo); //call make soap

在我正在开发的ASP.NETMVC4Web应用程序中。我有一个页面,它基本上通过从SOAP服务获取数据来生成报告

我的代码基本上是这样的

List<CustomThings> serverInfos = ServerInfos;
serverInfos.AsParallel().ForAll(srvInfo =>
{
    SoapHttpClientProtocol soapProxy = CreateProxy(srvInfo);
    //call make soap calls through the soap client
    //store results in the proper places
}
List serverInfos=serverInfos;
serverInfos.AsParallel().ForAll(srvInfo=>
{
SoapHttpClientProtocol soapProxy=CreateProxy(srvInfo);
//调用通过soap客户端进行soap调用
//将结果存储在适当的位置
}
我之所以在这里使用AsParalle,是因为以串行方式通过HTTP执行多个请求需要花费很长时间。我应该指出,这段代码确实有效,但偶尔也会运行

有没有可能事情会以一种不可预测的方式被处理掉,而对于我在这里尝试做的事情来说,PLINQ不是一个好的解决方案

另一个线程问题是否可能导致错误,从而使soap客户端“放弃”

附加信息 此特定的soap代理正在与ArcGIS服务器通信。通常,您可以检查服务器日志,查看特定请求何时初始化以及请求是否失败。这些日志中没有显示任何内容


下面是一个内部异常堆栈跟踪的示例,我从AsParallel代码中获得

异常:System.AggregateException:发生一个或多个错误。 --->System.Net.WebException:基础连接已关闭:预期保持活动状态的连接已被关闭 服务器。-->System.IO.IOException:无法从服务器读取数据 传输连接:已存在的连接被 远程主机。-->System.Net.Sockets.SocketException:现有 连接被远程主机强制关闭 System.Net.Socket.Socket.Receive(字节[]缓冲区,Int32偏移量,Int32 尺寸,SocketFlags(SocketFlags)位于 System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,Int32偏移量, Int32大小)--内部异常堆栈跟踪的结束---at System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,Int32偏移量, System.Net.PooledStream.Read(字节[]缓冲区,Int32 偏移量,Int32大小)在 System.Net.Connection.SyncRead(HttpWebRequest请求,布尔值 userRetrievedStream,布尔probeRead)--内部异常结束 堆栈跟踪--at System.Web.Services.Protocol.WebClientProtocol.GetWebResponse(WebRequest (请求)在 System.Web.Services.protocol.HttpWebClientProtocol.GetWebResponse(WebRequest (请求)在 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(字符串 methodName,对象[]参数)位于 ESRI.ArcGIS.SOAP.FeatureServerProxy.Query(Int32 LayerRorTableId,字符串 定义表达式、QueryFilter QueryFilter、ServiceDataOptions ServiceDataOptions、字符串GdbVersion、双MaximumAllowableOffset) 在 System.Linq.Parallel.SelectQueryOperator
2.SelectQueryOperatorResults.GetElement(Int32
索引)位于System.Linq.Parallel.QueryResults
1.get_项(Int32索引) 在 System.Linq.Parallel.PartitionedDataSource
1.ListContiguousIndexRangeEnumerator.MoveNext(T&
currentElement、Int32和currentKey)位于
System.Linq.Parallel.PipelineSpoolingTask
2.SpoolingWork()位于 System.Linq.Parallel.SpoolingTaskBase.Work()位于 位于的System.Linq.Parallel.QueryTask.BaseWork(未使用的对象) System.Linq.Parallel.QueryTask.b__0(对象o)at 位于的System.Threading.Tasks.Task.InnerInvoke() System.Threading.Tasks.Task.Execute()


我不认为您对Soap-HTTP请求使用
aspallel
有什么严重的错误,我也不认为这是一个线程问题

然而,并行请求显然将客户机/服务器推到了连接限制的数量,这就是为什么您看到连接正在关闭的原因

我敢打赌,您的客户端、服务器或两者都没有配置为处理您正在发出的并发连接数。这就是为什么当您以串行方式运行请求时,它可以工作的原因

我猜您没有访问服务器配置的权限,所以您可以做的一件事是通过设置
parallelenumable.WithDegreeOfParallelism
设置来控制同时向服务器发出的并行请求的数量,如以下代码段所示:

.AsParallel()
.WithDegreeOfParallelism(15)
通过这种方式,您可以控制并行性,并且不会因为少量连接上的大量请求而导致服务器过载

关于客户端,您应该确保已将最大并发客户端连接数设置为适当的数目,以确保您的请求可以使用到服务器的单独连接,并防止重复使用可能导致保持活动的连接。 如果使用连接的请求数超过了保持活动状态的最大连接数,或者超过了超时设置,则服务器可以关闭连接

您可以使用
ServicePointManager.DefaultConnectionLimit
设置以编程方式设置客户端连接限制。例如,您可以将其设置为50:

System.Net.ServicePointManager.DefaultConnectionLimit = 50;
下面是使用配置文件将最大连接数设置为50的示例:

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

我使用“50”作为示例,您应该确定/计算/测量设置的最佳设置


还要确保在每次请求后正确处理HTTP连接,以防止连接超时。

PLINQ甚至不知道您的连接对象存在。它无法关闭它

仔细阅读信息:

远程主机已强制关闭现有连接

服务器以意外方式关闭了连接。您的客户端没有故障

准确解释异常是一项基本的调试技能。此信息就在异常消息中

也许你产生的能量太多了
.WithDegreeOfParallelism(10)