在WCF回调上收到的消息是乱序的

时间:2016-10-26 07:59:04

标签: c# multithreading wcf nettcpbinding

我遇到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()方法启动某种设备,并且该方法设备内部有两种状态“Starting”和“Ready”。当状态更改客户端通过MyServiceCallback类中的NotificationAvailable通知时。

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

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

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

1 个答案:

答案 0 :(得分:0)

我打赌你想要将InstanceContextMode更改为单线程。

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

  

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