【问题标题】:WCF duplex channel gets closed when using callbacksWCF 双工通道在使用回调时关闭
【发布时间】:2010-12-17 22:28:24
【问题描述】:

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

我需要为多个并发客户端提供服务,并维护会话,所以服务被装饰了

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

为了避免线程死锁,回调类被修饰为

[CallbackBehavior(UseSynchronizationContext=false)]

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

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

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

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

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

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

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

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

【问题讨论】:

  • code sn-ps 可以从客户端和服务端受益。

标签: wcf callback channel duplex


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      你应该在 WCF 包装类的顶部添加这个属性:

      [CallbackBehavior(UseSynchronizationContext=false)]
      

      来自 cauldwell.net:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多