c# - 在 WCF 回调中收到的消息乱序

标签 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
{
    ...
}

回调接口(interface):

[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 时,问题就消失了。

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

最佳答案

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

session 、实例化和并发详细信息 here .

The use of concurrency is related to the instancing mode. In PerCall instancing, concurrency is not relevant, because each message is processed by a new InstanceContext and, therefore, never more than one thread is active in the InstanceContext.

关于c# - 在 WCF 回调中收到的消息乱序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40256739/

相关文章:

ios - 用于高效排队线程安全回调的示例 Objective-C 代码

c++ - 支持多线程方法来构建数组中所有元素的集合吗?

.net - WCF 错误 "Could not establish secure channel for SSL/TLS ..."突然出现

wcf - 防止命名管道冲突

c# - #定义从C到C#的转换

c# - 将列表划分为子集

c# - 如何引用指令MySql.Data.MySqlClient来连接mysql数据库

Java FTP 无法在 SwingWorker 线程内工作

部署到 Azure 的 WCF 服务

c# - 具有两个访问级别的登录系统