2009-11-18 70 views
1

我的WCF服务使用netTcpBinding,并且有一个回调对象。WCF双工通道在使用回调函数时关闭

我需要服务多个并发客户端,和十个分量会议,所以服务上装饰有

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

为了避免线程死锁,回调类装饰有

[CallbackBehavior(UseSynchronizationContext=false)] 

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

问题是,有时频道的关闭无意义(ICommunicationObject.Closing事件被触发)。之后,我在任何后续服务电话中都会收到例外情况。

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

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

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

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

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

任何想法可能发生什么或如何识别问题?

+0

代码片段可能会从客户端和服务端受益。 – Perpetualcoder 2009-11-18 15:57:31

回答

9

我认为可能发生的事情是客户端错误的频道,因为它在收到回复消息时收到回复消息。在使用net.tcp的WCF中,回调和回复使用相同的通道。

通常,您不应该在请求/回复(IsOneWay = false)OperationContract方法体内调用回调方法。最安全的做法是在进行双面打印时,在合同中不会有任何请求/回复方法,但只要在返回之前不回调回调合同,就可以安全地使用它们。 (在例如从另一个工作线程返回之后,调用回调方法也可以)。

+0

+1很棒的信息。存储将来。 – x0n 2012-01-06 18:40:31

0

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

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

问题是我正在发送一个DataTable与对象类型的列。

0

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

[CallbackBehavior(UseSynchronizationContext=false)] 

从cauldwell.net:

的问题,事实证明,是ASP.NET使用(由默认)一个叫做SynchronizationContext的小东西。就我所知,我可以告诉 (我没有彻底研究过,说实话)它的一个工作 它确保任何回调都可以在UI线程上运行,因此 可以避免需要调用Control.Invoke你在WinForms中做。在 我的情况下,那个额外的锁给了一些适合的东西,它是 试图清理东西在一个线程,没有更多的, 因此NullReferenceException。