[英]WCF: calling self-hosted service from client callback handler
Problem: getting a deadlock exception message in the WCF client. 问题:在WCF客户端中收到死锁异常消息。
Scenario: 场景:
Service calls a client callback (this call is completely independent and is initiated by some condition on the server). 服务调用客户端回调(此调用是完全独立的,并由服务器上的某些条件启动)。
While inside the client callback function, the client calls a function in the service and that's when the deadlock exception is thrown: 在客户端回调函数内部时,客户端会在服务中调用一个函数,此时将引发死锁异常:
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. 如果要允许乱序消息处理,请在CallbackBehaviorAttribute上指定Reentrant或Multiple的ConcurrencyMode。
I tried to simplify the code as much as I can. 我尽力简化了代码。 I did read this article but still I cant find where the problem is: http://msdn.microsoft.com/en-us/library/cc294424.aspx I'd appreciate any suggestions.... 我确实读过这篇文章,但仍然找不到问题所在: http : //msdn.microsoft.com/zh-cn/library/cc294424.aspx我将不胜感激任何建议。
[ServiceContract(Namespace = "http://abc.com/Core", SessionMode = SessionMode.Required, CallbackContract = typeof(ISvcCallback))]
public interface ISvc
{
// One way only - does not wait until operation completes and returns
// Can initiate session
[OperationContract(IsOneWay = true)]
void Initialize(string appId);
[OperationContract(IsInitiating = false)]
Account GetCurrentAccount();
} }
public interface ISvcCallback
{
/// <summary>
/// Report status of the account
/// </summary>
/// <param name="acct"></param>
[OperationContract(IsOneWay=true)]
void AccountStatus(Account acct);
} }
Service Implementation
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class Svc : ISvc
{
public Account GetCurrentAccount()
{
SipAccount sipAcct = null;
try
{
Account acct = m_MyBusinessObject.GetCurrentAccount();
}
catch (Exception ex)
{
}
return Acct;
}
}
} }
public class CallbackHandler : WcfSipItfService.IWinSipItfCallback
{
public void AccountStatus(Account Acct)
{
try
{
// display accout status in UI by delegate-wrapped event
// delegate and event declarations are somewhere else
// and work fine...
if (DisplayAccountStatusEvent != null)
DisplayAccountStatusEvent(Acct);
}
catch (Exception ex)
{
....
}
}
private void OnDisplayAccountStatusEvent(Account acct)
{
// call service function results in deadlock
Account acct = GetCurrentAccount();
}
} }
The service is Duplex - uses WSDualHttpBinding. 服务是Duplex-使用WSDualHttpBinding。
The deadlock appears to be due to you making a new out bound call while processing a callback from the previous call. 死锁似乎是由于您在处理来自先前呼叫的回叫时进行了新的出局呼叫。
The error message states that you may be able to solve it by "specify ConcurrencyMode of Reentrant or Multiple on CallbackBehaviorAttribute". 错误消息指出,您可以通过“在CallbackBehaviorAttribute上指定Reentrant或Multiple的ConcurrencyMode”来解决此问题。
Edit 编辑
I missed the code that was off the screen. 我错过了屏幕上的代码。 Couple of things to check: 需要检查的几件事:
What's your client? 你的客户是什么? Is it a UI client? 它是UI客户端吗? if so, you need to add callbackBehavior UseSynchronizationContext=false to client that implements callback contract. 如果是这样,则需要向实现回调协定的客户端添加callbackBehavior UseSynchronizationContext = false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.