我遇到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时,问题就消失了。
解决此问题的正确方法是什么?
答案 0 :(得分:0)
我打赌你想要将InstanceContextMode
更改为单线程。
会话,实例化和并发详细信息here。
并发的使用与实例化模式有关。在PerCall 实例化,并发性是不相关的,因为每个消息都是 由新的InstanceContext处理,因此永远不会超过一个 线程在InstanceContext中处于活动状态。