0

问题:在 WCF 客户端中收到死锁异常消息。

设想:

  1. 服务调用客户端回调(此调用完全独立,由服务器上的某些条件发起)。

  2. 在客户端回调函数内部,客户端调用服务中的一个函数,此时会引发死锁异常:

此操作会死锁,因为在当前消息完成处理之前无法接收到回复。如果要允许无序消息处理,请在 CallbackBehaviorAttribute 上指定 Reentrant 或 Multiple 的 ConcurrencyMode。

我试图尽可能地简化代码。我确实读过这篇文章,但我仍然找不到问题所在:http: //msdn.microsoft.com/en-us/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();

    }

}

该服务是双工的 - 使用 WSDualHttpBinding。

4

2 回答 2

1

死锁似乎是由于您在处理上一个调用的回调时进行了新的出站调用。

错误消息指出,您可以通过“在 CallbackBehaviorAttribute 上指定 Reentrant 或 Multiple 的 ConcurrencyMode”来解决它。

编辑

我错过了屏幕外的代码。几件事要检查:

  • 为什么需要单实例模式?
  • 更改并发模式后是否更新了服务引用?
于 2012-04-25T19:09:36.390 回答
0

你的客户是什么?它是一个 UI 客户端吗?如果是这样,您需要将 callbackBehavior UseSynchronizationContext=false 添加到实现回调合约的客户端。

于 2012-07-20T08:08:38.070 回答