我自我托管的wcf双工回拨服务存在问题。我得到一个InvalidOperationException
与消息:防止WCF双工回拨服务造成死锁问题
此操作会死锁,因为答复不能接收 直到当前消息完成处理。如果您希望允许 乱序消息处理,请指定Reentrant的并发模式 或Multiple on CallbackBehaviorAttribute。
这里是我的服务行为:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = true)]
这里是我的服务合同:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IClientCallback))]
[ServiceContract]
public interface IClientToService
{
[OperationContract(IsOneWay = false)]
LVSSStatus GetLvssStatus();
[OperationContract(IsOneWay = true)]
void PickSpecimen(long trackingNumber, int destCode);
[OperationContract(IsOneWay = true)]
void CancelCurrentPickTransaction();
}
这里是我的回调接口:
public interface ILvssClientCallback
{
[OperationContract(IsOneWay = true)]
void SendClientCallback(LvssCallbackMessage callbackMessage);
[OperationContract(IsOneWay = false)]
List<SpecimenTemplateDescriptor> GetTemplateDescriptorList(DrawerLayout drawerLayout);
[OperationContract(IsOneWay = false)]
SpecimenTemplate SelectSpecimenTemplate(string templateName, int version);
[OperationContract]
void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol,
int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError);
[OperationContract]
void LvssRobotStatusChange(LVSSStatus status);
}
我明白InvalidOperationException
是回调操作时引起的on在客户端上调用时,该服务已被锁定以处理当前操作。所以发生死锁。
我已经尝试将我的ConcurrencyMode更改为多个,并将UseSynchronizationContext更改为false。
我仍然看到两个问题,我的服务:
第一:以下服务操作冻结我的客户端的WPF应用程序时GetLvssStatus()
迅速调用(通过点击UI按钮,迅速地)。这种方法不是一种方法,并且从服务中同步返回一个枚举类型返回给客户端。
[OperationContract(IsOneWay = false)]
LVSSStatus GetLvssStatus();
*这是什么导致我的wpf应用程序冻结? *如何防止应用程序冻结? 如果我使用backgroundworker线程作为异步调用,则应用程序不会冻结。我真的需要这种方法同步工作。
二:当我指定回调方法LvssRobotStatusChange到IsOneWay = true
,我得到一个的ObjectDisposedException:无法访问已释放的对象。对象名称:'System.ServiceModel.Channels.ServiceChannel'
。
[OperationContract(IsOneWay = true)]
void LvssRobotStatusChange(LVSSStatus status);
*什么原因导致此ObjectDisposedException? *在这种情况下可以忽略IsOneWay作业吗?在这种情况下省略IsOneWay允许回调在没有任何例外的情况下完成。
*这些问题可能是缺少线程安全代码的结果吗?
*如果是这样,那么使ConcurrencyMode.Multiple服务行为线程安全的最佳做法是什么?
这些问题的任何帮助,非常感谢。
* FIRST EDIT 有关创建我的双工信道的更多信息。我的wpf视图模型创建了一个负责处理我的频道创建的代理对象。在服务尝试使用回调对象时,到目前为止在我的通道上设置客户端上新线程的任何尝试都会导致ObjectDisposedException。
*第二个编辑 我相信我的服务应该工作,如果我能得到与无效的方法操作合同设置IsOneWay =真。在重入并发的情况下,主通道线程应该允许这些方法通过,而不管任何锁定。
这是我的回调接口:
public interface ILvssClientCallback
{
[OperationContract(IsOneWay = true)]
void SendClientCallback(LvssCallbackMessage callbackMessage);
[OperationContract]
List<SpecimenTemplateDescriptor> GetTemplateDescriptorList(DrawerLayout drawerLayout);
[OperationContract]
SpecimenTemplate SelectSpecimenTemplate(string templateName, int version);
[OperationContract(IsOneWay = true)]
void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol,
int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError);
[OperationContract(IsOneWay = true)]
void LvssRobotStatusChange(LVSSStatus status);
}
当我设置方法LvssRobotStatuschange操作合同IsOneWay =真,我的缓存回调通道抛出一个CommunicationObjectAbortedException。出于某种原因,我的回调属性正在中止。
***什么会导致回调通道中止?
什么是您的应用程序托管(服务或回调接口)? –
我的应用程序正在托管回调接口。从我的wpf视图模型中,我创建了一个负责创建代理和双工通道的代理类。然后我调用该类上的Connect()来创建双工通道。代理类负责为我的客户端实现回调接口。在我的情况下,总会有一个服务和一个客户。 – EnLaCucha