双工WCF服务在第11次呼叫时挂起

时间:2009-07-17 01:55:34

标签: wcf duplex

我有一个双工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次测试后,下一次调用服务都会挂起。

对我可能做错了什么的想法?

5 个答案:

答案 0 :(得分:5)

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

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

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

但我仍然感到疑惑,为什么我会遇到这个问题,因为我特意关闭了一个代理,然后继续下一个。 2的MaxConcurrentXXX应该在这种情况下工作;我不需要500的MaxConcurrentXXX。如果每个连接到服务器的客户端在实际连接之后继续咀嚼连接,我就会担心可扩展性。

也许我在其他地方犯了一个愚蠢的错误 - 这不是第一次 - 但我已经专门介绍了关闭代理的代码,而且它肯定会被调用。

答案 1 :(得分:0)

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

是否未正确发布任何服务器端资源或锁?由于您的服务实例是每个会话,我怀疑服务器对象是挂在一起并持有一个锁。如果您将行为更改为每次通话该怎么办?

答案 2 :(得分:0)

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

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并在启动后将调试器附加到服务进程。

答案 3 :(得分:0)

查看ServiceBehavior.AutomaticSessionShutdown。

答案 4 :(得分:0)

在客户端使用的Callback函数开始时 OperationContext.Current.Channel.Close();

这样可以解决问题。