WCF 回调中收到的消息有问题

Posted

技术标签:

【中文标题】WCF 回调中收到的消息有问题【英文标题】:Messages received on WCF callback are out of order 【发布时间】:2017-03-08 11:49:37 【问题描述】:

我遇到了 WCF 双工服务问题。

这是我的服务接口:

[DeliveryRequirements(RequireOrderedDelivery = true)]
[(CallbackContract = typeof(IMyNotification), SessionMode = SessionMode.Required)]
public interface IMyService
 
    [OperationContract]
    void StartSomething();      
    ...

服务实现:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyService : IMyService

    ...

回调接口:

[DeliveryRequirements(RequireOrderedDelivery = true)]
public interface IMyNotification

    [OperationContract (IsOneWay=true)]
    void NotificationAvailable(Notification notification);

客户端回调实现:

[CallbackBehavior (ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
class MyServiceCallback : IMyNotification

    public void NotificationAvailable(Notification notification)
    
            lock (_NotificationLock)
            
                // process notification...
            
    

假设 StartSomething() 方法启动某种设备,并且在该方法内部,设备从“正在启动”和“就绪”两种状态进入。当状态更改时,通过 MyServiceCallback 类中的 NotificationAvailable 通知客户端。

问题是有时在 NotificationAvailable 方法消息中 即使设置了已订购的交付,也没有以正确的顺序收到(正确的顺序是“开始”->“就绪”,但回调接收“就绪”>“开始”)。

这通常发生在第一次调用 StartSomething() 方法时。这似乎是某种线程竞争条件。当我在 MyServiceCallback 上设置 ConcurrencyMode = ConcurrencyMode.Single 时,问题就消失了。

解决此问题的正确方法是什么?

【问题讨论】:

【参考方案1】:

我敢打赌,您想将 InstanceContextMode 更改为单线程。

会话、实例化和并发详细信息here。

并发的使用与实例化模式有关。在 PerCall 中 实例化,并发是不相关的,因为每条消息都是 由新的 InstanceContext 处理,因此不会超过一个 线程在 InstanceContext 中处于活动状态。

【讨论】:

以上是关于WCF 回调中收到的消息有问题的主要内容,如果未能解决你的问题,请参考以下文章

WCF:单向回调有问题

如何在双工回调中读取 WCF 消息头?

如何在 IIS 中正确托管连接到 SQLServer 的 WCF 数据服务?为啥我会收到错误消息?

WCF + JSONP:总是收到“方法不允许”错误消息

在“手动”发送肥皂消息时,我收到 WCF 的 AddressingNone 错误

WCF:使用带有消息契约的流式传输