有人可以告诉我如何在没有发生死锁的情况下从回调中调用WCF服务的属性吗?
我尝试将[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]添加到实现回调的类中,但没有成功。
该服务具有以下属性:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
public class SAPUploadService : ISAPUploadService
{
谢谢MM
这是调用Callback方法的代码
foreach (var otherConnection in _users.Keys)
{
SAPUploadInstruction ins = AddMessageToInstruction(message);
ins.UserName = user.UserName;
Task.Factory.StartNew(() =>
{
otherConnection.ReceiveInstruction(ins);
});
这是ReceiveInstruction的回调实现
public void ReceiveInstruction(SAPUploadInstruction instruction)
{
// fire this objects call back....
if (OnReceiveInstruction != null) OnReceiveInstruction(this, instruction);
}
在上面,事件OnReceiveInstruction附加到UI。这按如下方式处理:
public void ReceiveInstruction(object sender, SAPUploadInstruction instruction)
{
DispatchIfNecessary(() => {
ProcessInstruction(instruction);
});
}
上述方法 - ProcessInstruction - 根据服务属性/功能设置各种控件。这就是死锁,即Label1.Content = myService.SomeProperty。
BTW,DispatchIfNecessary实现为:
public void DispatchIfNecessary(Action action)
{
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
答案 0 :(得分:0)
在DispatchIfNecessary
中使用Invoke
的异步版本,因此您的回调将不会等待完成UI更改,因为UI线程正在等待回调处理的结束(因此我们无法完成)陷入僵局):
Dispatcher.BeginInvoke(action);