【问题标题】:Duplex WCF service hangs on 11th call双工 WCF 服务在第 11 次调用时挂起
【发布时间】:2009-07-17 01:55:33
【问题描述】:

我有一个双工 WCF 服务,它在神奇的 10 个代理实例化之后挂起。客户端的具体错误是:

“System.TimeoutException:发送到 net.tcp://localhost:8080/RoomService/netTcp 的此请求操作未在配置的超时 (00:00:59.9960000) 内收到回复”。

服务器上没有任何明显的错误消息。

请注意,这不是标准的、明显的问题,即无法关闭我的代理连接,因为我在打开下一个代理连接之前适当地关闭了代理连接的每个实例:

try
{
    client.Close();
}
catch (CommunicationException)
{
    client.Abort();
}
catch (TimeoutException)
{
    client.Abort();
}
catch (Exception)
{
    client.Abort();
    throw;
}

并且我已将我的限制行为设置为 500 个同时处理所有内容:

ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
    MaxConcurrentCalls = 500,
    MaxConcurrentSessions = 500,
    MaxConcurrentInstances = 500
};

我已将服务的 ConcurrencyMode 设置为 Multiple,并尝试了 InstanceContextMode 的所有三个可能值。

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]

我已尝试自行托管该服务,并将其托管在 IIS 中,但我得到了相同的结果。

我已经尝试过 NetTcpBinding、WSDualHttpBinding 和 PollingDuplexBinding(在 Silverlight 上),每个结果都相同。我不能尝试 BasicHttpBinding 或 WSHttpBinding,因为这是一个双工服务。

在我的代码中有一个地方我启动了多个线程(以同时执行多个回调),但出于故障排除的目的,我已经注释掉了这一点,它并没有产生任何影响。

在客户端上,我尝试为每个测试使用新代理,并在所有测试中重复使用相同的代理,但没有任何运气。我尝试为每个代理创建一个新的 InstanceContext,并在所有代理中重用相同的 InstanceContext,但还是没有运气。

无论我做什么,在我的测试工具中执行第 10 次测试后,下一次对服务的调用都会挂起。

有什么想法我可能做错了吗?

【问题讨论】:

  • 听起来像是恐怖电影的片名。 “第 11 次通话”
  • 如果你过去几天一直在过着我的生活,试图找出这个问题,你会在评估中发现某种讽刺:-)。
  • 我遇到了基本相同的问题。你解决了吗?
  • 我从未真正解决它,但我设法围绕它编写代码。我最终在客户端代码中花费了大量时间,以确保将打开的客户端数量减少到最低限度。换句话说,我没有打开客户端然后关闭它,而是将其保持打开并重用它,并且仅在绝对必要时才关闭它。我需要使用 Silverlight 4.0(和 .NET 4.0)再试一次,但我还没有机会。

标签: wcf duplex


【解决方案1】:

好的,所以我至少犯了一个愚蠢的错误:我正在创建限制行为,但忽略了将其添加到适当的服务中。现在已正确添加:

ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
    MaxConcurrentCalls = 500,
    MaxConcurrentSessions = 500,
    MaxConcurrentInstances = 500
};
base.Description.Behaviors.Add(throttlingBehavior);

现在我可以运行 10 多个测试,因此我的直接问题解决了。

但我仍然对为什么会遇到这个问题感到困惑,因为我在继续下一个代理之前专门关闭了一个代理。 MaxConcurrentXXX 为 2 应该在这种情况下工作;我不应该需要 500 的 MaxConcurrentXXX。如果连接到服务器的每个客户端在实际连接时间之后继续破坏连接,我有点担心可伸缩性。

也许我在其他地方犯了一个愚蠢的错误——这不会是第一次——但我已经专门单步执行了关闭代理的代码,并且肯定会被调用。

【讨论】:

    【解决方案2】:

    当我在服务器端有一个信号量时发生了这种情况,该信号量在客户端完成服务后没有被释放。

    是否有任何服务器端资源或锁未正确释放?由于您的服务实例是每个会话的,我怀疑服务器对象正在徘徊并持有锁。如果您将行为更改为每次调用会怎样?

    【讨论】:

    • 感谢您的回复。我已经尝试(并且刚刚重试)了 InstanceContext 的所有三个值,但它们都具有相同的结果。我已经在我的代码中搜索了任何没有正确关闭的资源,并且只是为了它,已经注释掉了任何可能阻止资源被垃圾收集的东西。我会继续寻找:-)。
    • 特别注意静态数据,因为它们在调用期间也保存在 AppDomain 中,这意味着 InstanceContext 值不会影响它们。
    【解决方案3】:

    我没有答案,但我有一些调试建议。

    1) 将 Visual Studio 调试器附加到服务进程,看看它是否可以捕获正在发生的任何事情。

    2) 配置服务行为,将异常信息传回客户端,查看服务是否抛出未报告的异常:

    <behaviors>
        <serviceBehaviors>
            <behavior name="ServiceBehavior">
                <serviceDebug includeExceptionDetailInFaults="True"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    

    3) 在启用 ActivityTracing 的情况下打开服务日志记录并使用服务跟踪查看器(来自Windows SDK)分析日志并查看是否弹出任何内容

    <system.diagnostics>
        <trace autoflush="true" />
        <sources>
            <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
                <listeners>
                    <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Service.svclog"  />
                </listeners>
            </source>
        </sources>
    </system.diagnostics>
    

    4) 将服务包装器与功能代码隔离开来,看看服务是否仍然挂起。如果没有,则逐步添加功能,直到您找出导致它挂起的原因

    5) 如果您使用的是 HTTP 绑定,请使用 fiddler 代理服务并记录 http 流量。

    6) 尝试Hosting the WCF service in a Managed Windows Service 并在启动后将调试器附加到服务进程。

    【讨论】:

    • 谢谢! #1、#2、#3 - 完成了所有这些 :-(。我没有发现任何似乎有用的东西。我会给 #4 一个机会。
    • 为了它的价值,我尝试了 #4,即切换我的测试工具以直接调用服务库(例如,不通过服务主机),并且没有任何问题。所以这肯定与服务本身有关。
    【解决方案4】:

    看看 ServiceBehavior.AutomaticSessionShutdown。

    【讨论】:

      【解决方案5】:

      在客户端使用回调函数的开头 OperationContext.Current.Channel.Close();

      这将解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-19
        • 2012-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-03
        • 1970-01-01
        • 2011-05-12
        相关资源
        最近更新 更多