gpt4 book ai didi

.net - 防止 WCF 双工回调服务出现死锁问题

转载 作者:行者123 更新时间:2023-12-04 00:42:30 25 4
gpt4 key购买 nike

我有一个自托管 wcf 双工回调服务的问题。我得到一个 InvalidOperationException带有消息:

This operation would deadlock because the reply cannot be received until the current message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on CallbackBehaviorAttribute.



这是我的服务行为:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode =  ConcurrencyMode.Reentrant, UseSynchronizationContext = true)]

这是我的服务契约(Contract):
 [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();
}

这是我的回调接口(interface):
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是在客户端调用回调操作时导致的,服务已被锁定以处理当前操作。因此,发生了死锁。

我尝试将我的 ConcurrencyMode 更改为多个,并将 UseSynchronizationContext 更改为 false。

我的服务仍然存在两个问题:

第一:以下服务操作会在 GetLvssStatus() 时卡住我的客户端 wpf 应用程序被快速调用(通过快速单击 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 服务行为线程安全的最佳实践是什么?

非常感谢您对这些问题的任何帮助。

* 第一次编辑
关于创建我的双工 channel 的更多信息。我的 wpf View 模型创建了一个代理对象,负责处理我的 channel 的创建。到目前为止,当服务尝试使用回调对象时,任何尝试在客户端的新线程上设置我的 channel 都会导致 ObjectDisposedException。

* 第二次编辑
我相信如果我可以使用 void 方法获取操作契约(Contract)来设置 IsOneWay = true,我的服务应该可以工作。在可重入并发的情况下,主 channel 线程应该让这些方法通过,而不管任何锁定。
这是我的回调接口(interface):
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 操作契约(Contract)设置为 IsOneWay = true 时,我的缓存回调 channel 会引发 CommunicationObjectAbortedException。由于某种原因,我的回调属性被中止。

***什么会导致回调 channel 中止?

最佳答案

我以前遇到过这个,this link应该有所帮助,其中讨论了在应用程序主线程以外的线程上创建 channel 。

关于.net - 防止 WCF 双工回调服务出现死锁问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14393386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com