【问题标题】:WCF proxy connection open causes errorsWCF 代理连接打开导致错误
【发布时间】:2026-02-04 17:25:01
【问题描述】:

我们在中间层使用托管在 IIS 上的 WCF 服务并使用 WPF 客户端。 我们在生产日志中看到了这些错误。从谷歌我被指向一个链接http://kennyw.com/indigo/150,它清楚地表明这个错误与 MaxConcurrentSessions 有关。

下面的生产日志详细信息表明,当 WPF 客户端尝试使用 ICommunicationObject.Open() 打开 WCF 代理连接时会发生错误 我们的生产系统上的这个错误经常发生,但我无法在我的本地设置上重现这个错误。我尝试将 MaxConcurrentSessions 更改为 1,然后打开 WPF 应用程序的 5 个实例,在 WPF 应用程序上,默认仪表板每 1 分钟运行一次计时器以尝试获取数据,但我仍然无法重现此错误。

我的问题实际上是这个错误何时发生,从上面的链接中它说当服务器压力过大时会发生这种情况,但在我上面的测试用例中它应该已经加载。我还需要能够重现此问题才能尝试修复。

如果我在正确的道路上的任何想法,MaxConcurrentSessions 是否是正确的查看位置以及我如何在本地模拟它。请帮忙。

2/16/2012 4:10:40 PM:Information:Exception in the ServiceCall constructor:       System.ServiceModel.CommunicationException: 
  The socket connection was aborted. 
  This could be caused by an error processing your message or a receive timeout being   exceeded by the remote host, or an underlying network resource issue. 
  Local socket timeout was '00:00:59.9687730'. --->System.Net.Sockets.SocketException: 
An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
 --- End of inner exception stack trace ---
 Server stack trace: 
 at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
 at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
 at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
 at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade       (StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
 at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
 at  System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
 at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
 at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)

【问题讨论】:

    标签: wcf wcf-client


    【解决方案1】:

    问题的根本原因很可能是 WPF 应用程序中服务代理实例的不当处置。查看代理是如何实例化和处置的。

    如果您的代码没有遵循SO question 的答案中描述的模式之一,那么您没有正确释放 TCP 连接。当使用依赖于 TCP 会话的绑定时,这个问题最容易弹出。

    【讨论】:

    • 我们对每个连接都使用 using 块;重写 Idispose 以删除对象,这是一种干净的方法。 --------------------------------public void TryCloseOrAbort(ICommunicationObject obj) { if (obj != null) { if ( obj.State != CommunicationState.Faulted && obj.State != CommunicationState.Closed) {try { obj.Close(); } 捕捉 (CommunicationObjectFaultedException) { obj.Abort(); } 捕捉(超时异常){ obj.Abort(); } catch (Exception){obj.Abort();throw;} }else obj.Abort();}}
    • 我在该代码中看到的唯一有点奇怪的是它可以在具有 obj.State == CommunicationState.Closed 的 obj 实例上调用 Abort()。尝试检查ICommunicationObject documentation,看看这是否会导致处置过程中出现问题。
    • 感谢您对 Sixto 的回复,该链接显示在关闭的通信状态值上调用中止不会导致问题“如果当前状态为关闭或对象已关闭,则 Abort() 方法不执行任何操作在 " 之前终止,所以它不应该导致我看到的这个问题。嗯,你认为错误只是因为 using 块吗? -------------------------------------------------- -使用 (var svc = new ServiceCall(endpointName)) { serviceCallType = svc.GetType(); // 调用服务调用的调用者实现 serviceCallBody(svc); }
    • 所有 using 语句所做的就是将您的代码包装在 try { //your code } finally { //dispose of the instance created in the using line } 中。如果你重写 Dispose(),它只是调用你的 dispose 逻辑。验证您的代码是否正确处理代理实例的唯一方法是使用WinDbg 分析应用程序的内存转储。查看代理实例的特定 .NET 类型的垃圾收集堆(命令是 !dumpheap -type YourType)并查看它们是否在 gcroot 链中。
    【解决方案2】:

    该错误可能有几个原因。 MaxConcurrentSessions 就是其中之一。

    在服务器和客户端的配置文件中,请务必增加 receiveTimeoutsendTimeout。您可能超出了这些参数所允许的时间。

    您需要确保服务器和客户端对这些字段具有相同的配置值。如果只更改其中一个,另一个仍然可能提前超时。

    除此之外,他们的 XML 配置的 MS 参考如下,可以帮助您找到导致问题的原因。

    http://msdn.microsoft.com/en-us/library/ms731354.aspx

    【讨论】:

      【解决方案3】:

      将此行放在Consumer端的App.Config中

      <system.net>
         <defaultProxy useDefaultCredentials="true">
           <proxy usesystemdefault="True" bypassonlocal="True"/>
        </defaultProxy>
       </system.net>
      

      【讨论】:

        最近更新 更多