【问题标题】:Can Linq AsParallel() dispose of SoapHttpClientProtocol objects prematurely?Linq AsParallel() 可以过早地处理 SoapHttpClientProtocol 对象吗?
【发布时间】:2014-12-06 02:13:20
【问题描述】:

在我正在开发的 ASP.Net MVC 4 Web 应用程序中。我有一页基本上通过从 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
}

我在这里使用 AsParallel 的原因是因为通过 HTTP 以串行方式执行多个请求需要很长时间。我应该指出这段代码确实有效,虽然偶尔

是否有可能事情以一种不可预测的方式被处理掉了,而 PLINQ 不是我在这里尝试做的一个好的解决方案?

是否有可能另一个线程问题可能导致导致soap客户端“放弃”的错误?

附加信息

这个特定的 soap 代理正在与 ArcGIS Server 通信。通常,您可以检查服务器日志并查看特定请求何时启动以及请求是否失败。这些日志中没有显示任何内容。


这是我从 AsParallel 代码中获得的内部异常堆栈跟踪的示例。

异常:System.AggregateException:发生一个或多个错误。 ---> System.Net.WebException:底层连接已关闭:预期保持活动状态的连接被 服务器。 ---> System.IO.IOException: 无法从 传输连接:现有连接被强行关闭 远程主机。 ---> System.Net.Sockets.SocketException:现有的 连接被远程主机强行关闭 System.Net.Sockets.Socket.Receive(Byte[] 缓冲区,Int32 偏移量,Int32 大小,SocketFlags socketFlags)在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量, Int32 大小)---内部异常堆栈跟踪结束---在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量, Int32 大小)在 System.Net.PooledStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)在 System.Net.Connection.SyncRead(HttpWebRequest 请求,布尔值 userRetrievedStream, Boolean probeRead) --- 内部异常结束 堆栈跟踪 --- 在 System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest 请求)在 System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest 请求)在 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(字符串 方法名,对象 [] 参数)在 ESRI.ArcGIS.SOAP.FeatureServerProxy.Query(Int32 LayerOrTableID,字符串 定义Expression、QueryFilter QueryFilter、ServiceDataOptions ServiceDataOptions, String GdbVersion, Double MaximumAllowableOffset) 在 System.Linq.Parallel.SelectQueryOperator2.SelectQueryOperatorResults.GetElement(Int32 index) at System.Linq.Parallel.QueryResults1.get_Item(Int32 索引) 在 System.Linq.Parallel.PartitionedDataSource1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey) at System.Linq.Parallel.PipelineSpoolingTask2.SpoolingWork() 在 System.Linq.Parallel.SpoolingTaskBase.Work() 在 System.Linq.Parallel.QueryTask.BaseWork(对象未使用)在 System.Linq.Parallel.QueryTask.<.cctor>b__0(Object o) at System.Threading.Tasks.Task.InnerInvoke() 在 System.Threading.Tasks.Task.Execute()

【问题讨论】:

    标签: c# asp.net-mvc-4 soap-client plinq arcgis-server


    【解决方案1】:

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

    仔细阅读消息:

    一个现有的连接被远程主机强行关闭。

    服务器以意外的方式关闭了连接。你的客户没有错。

    准确解释异常是一项必不可少的调试技能。此信息就在异常消息中。

    也许您正在产生过多的负载。设置可持续的并行度。默认启发式是针对 CPU 工作,而不是针对 IO。

    .WithDegreeOfParallelism(10)
    

    本应保持活动的连接已被服务器关闭。

    这可能意味着服务器不支持 HTTP 保持活动。

    【讨论】:

    • 我可能怀疑客户端的唯一原因是我在测试用例中只有 5 或 6 个“CustomThings”(并行度只有 5 或 5)。另一个原因是我正在与一个专有的 10.2 ArcGis 服务器通信,它应该(并且旨在)处理大量的数据库/服务器请求。
    • 在这种情况下,我建议使用 Fiddler 查看 HTTP 级别的错误。查看是否设置了 keep-alive 并且未遵守。接下来是 Wireshark 跟踪,以确认远程端关闭了连接(使用 RST)。该消息清楚地表明情况就是这样。
    【解决方案2】:

    我不认为您对您的 Soap HTTP 请求使用 AsParallel 做任何严重错误,而且我认为这不是线程问题。

    但是,并行请求显然会将您的客户端/服务器推到连接数限制,这就是您看到连接关闭的原因。

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

    我猜你无权访问服务器配置,所以你可以做的一件事是通过设置ParallelEnumerable.WithDegreeOfParallelism 设置来控制同时向服务器发出的并行请求的数量,如下面的 sn -p:

    .AsParallel()
    .WithDegreeOfParallelism(15)
    

    这样您就可以控制并行性,并且不会冒着在少量连接上发送大量请求而使服务器过载的风险。

    关于客户端,您应该确保已设置最大值。将并发客户端连接数设置为适当的数量,以确保您的请求可以使用与服务器的单独连接,并防止重复使用可能导致您的 Keep-Alive 问题的连接。 如果使用连接的请求数超过保持连接的最大连接数或超过超时设置,服务器可以关闭连接

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

    System.Net.ServicePointManager.DefaultConnectionLimit = 50;
    

    这是一个示例设置最大值。使用配置文件连接到 50:

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

    我以“50”为例,您应该确定/计算/测量最适合您的设置的设置。

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

    【讨论】:

      猜你喜欢
      • 2014-08-06
      • 2011-04-12
      • 2019-12-24
      • 2013-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      相关资源
      最近更新 更多