1

我的 WCF 服务使用 netTcpBinding,并且有一个回调对象。

我需要为多个并发客户端提供服务,并维护会话,因此服务装饰有

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

为了避免线程死锁,回调类用

[CallbackBehavior(UseSynchronizationContext=false)]

我用来SynchronizationContext在 UI 线程中执行该方法。

问题是有时通道 gest 无缘无故关闭(ICommunicationObject.Closing事件被触发)。之后,我在任何后续服务调用中都会遇到异常。

查看跟踪文件,最后一条消息是回调调用,但是,回调方法永远不会被调用。没有例外。

经过一些调试后,我发现只有在同步操作中间进行回调调用时才会发生这种情况。步骤是这样的:

  1. 调用服务A方法IsOneWay=true
  2. 调用服务B方法IsOneWay=false
  3. A调用回调方法,但B仍在执行。

这应该不是问题,因为回调有UseSynchronizationContext=false,因此回调调用可以在单独的线程中进行。

我无法在更简单的情况下重现该问题。在一个简单的项目中按照这些步骤成功执行。

对可能发生的事情或如何识别问题有任何想法吗?

4

3 回答 3

10

我认为可能发生的情况是客户端出现故障,因为它在期待回复消息时收到了回调消息。在带有 net.tcp 的 WCF 中,回调和回复使用相同的通道。

通常,您永远不应在请求/回复 (IsOneWay=false) OperationContract 方法的主体内调用回调方法。最安全的做法是在执行双工时在您的合约中没有任何请求/回复方法,但只要它们在返回之前不回调回调合约,您就可以安全地拥有它们。(可以返回后调用回调方法,例如从另一个工作线程)。

于 2009-11-20T20:39:57.057 回答
0

您应该在 WCF 包装器类的顶部添加此属性:

[CallbackBehavior(UseSynchronizationContext=false)]

来自 cauldwell.net:

事实证明,问题在于 ASP.NET(默认情况下)使用了一个叫做 SynchronizationContext 的小东西。据我所知(说实话,我还没有彻底研究过)其中一项工作是确保在 UI 线程上运行任何回调,从而避免像你一样调用 Control.Invoke赢表格。在我的情况下,那个额外的锁正在给出一些合适的东西,它试图清理一个不再存在的线程上的东西,因此是 NullReferenceException。

于 2012-07-11T06:08:11.023 回答
0

感谢您的回复!我可以解决错误。

这是一个序列化问题,我IncludeExceptionsInFaults=true在服务和回调行为属性中添加,然后我能够看到错误。

问题是我发送了一个包含对象类型列的 DataTable。

于 2009-11-25T11:40:27.177 回答