双工 WCF 服务在第 11 次调用时挂起

发布于 2024-07-27 22:27:25 字数 1418 浏览 8 评论 0原文

我有一个双工 WCF 服务,它在 magic 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,但同样没有成功。

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

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

I've got a duplex WCF service which hangs after the magic 10 proxy instantiations. The specific error on the client is:

"System.TimeoutException: This request operation sent to net.tcp://localhost:8080/RoomService/netTcp did not receive a reply within the configured timeout (00:00:59.9960000)".

There aren't any apparent error messages on the server.

Note that this isn't the standard, obvious problem, i.e., failing to close my proxy connections, as I'm closing every instance of my proxy connection appropriately before opening the next one:

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

And I've set my throttling behavior to 500 simultaneous everything:

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

I've set the ConcurrencyMode of my service to Multiple, and I've tried all three possible values for InstanceContextMode.

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

I've tried self-hosting the service, and hosting it within IIS, and I get the same results on each.

I've tried the NetTcpBinding, the WSDualHttpBinding, and the PollingDuplexBinding (on Silverlight), with the same results on each. I can't try the BasicHttpBinding or the WSHttpBinding, as this is a duplex service.

There was one place in my code where I was launching multiple threads (to execute multiple callbacks simultaneously), but for troubleshooting purposes I've commented that bit out, and it hasn't made a difference.

On the client, I've tried using new proxies for each test, and reusing the same proxy across all tests, but without any luck. I've tried creating a new InstanceContext for each proxy, and reusing the same InstanceContext across all proxies, and again, no luck.

Whatever I do, after the 10th test executed in my test harness, the next call to the service hangs.

Any thoughts on what I might be doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

┈┾☆殇 2024-08-03 22:27:26

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

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) 尝试在托管 Windows 服务中托管 WCF 服务并附加服务进程启动后的调试器。

I don't have an answer but I do have some debugging advice.

1) Attach the visual studio debugger to the service process and see if it can catch whatever is going on.

2) Configure the service behavior to pass exception information back to the client and see if the service is throwing an exception that isn't being reported:

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

3) Turn on service logging with ActivityTracing enabled and use the Service Trace Viewer (from Windows SDK) to analyze the log and see if anything pops up

<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) Isolate the service wrapper from the functional code and see if the service still hangs. If it doesn't then incrementally add functionality back until you figure out what is making it hang

5) If you are using an HTTP binding, proxy the service with fiddler and log the http traffic.

6) Try Hosting the WCF service in a Managed Windows Service and attach a debugger to the service process after you start it up.

杀お生予夺 2024-08-03 22:27:26

看一下 ServiceBehavior.AutomaticSessionShutdown。

Take a look at ServiceBehavior.AutomaticSessionShutdown.

浮世清欢 2024-08-03 22:27:26

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

这将解决问题。

At the begining of the Callback function in the client use
OperationContext.Current.Channel.Close();

This will solev the problem.

向日葵 2024-08-03 22:27:25

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

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

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

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

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

OK, so I made at least one stupid mistake: I was creating the throttling behavior, but was neglecting to add it to the service proper. It's now added correctly:

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

And now I can run more than 10 tests, and hence my immediate problem is solved.

But I'm still puzzled as to why I'm running into this problem at all, since I'm specifically closing one proxy before moving on to the next. A MaxConcurrentXXX of 2 ought to be working in this scenario; I shouldn't need a MaxConcurrentXXX of 500. I'm a tad worried about scalability if every client that connects to the server continues to chew up a connection beyond the time that it's actually connected.

Maybe I'm making a stupid mistake somewhere else -- it wouldn't be the first time -- but I've specifically stepped through the code that's closing the proxy, and it's definitely getting called.

尽揽少女心 2024-08-03 22:27:25

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

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

I've had this happen when I had a semaphore on the server-side which wasn't being released after a client was done being serviced.

Are any server-side resources or locks not being released properly? Since your service instance is per session, I'd suspect that the server object is hanging around and holding a lock. What if you change the behavior to per call?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文