【问题标题】:WCF: calling self-hosted service from client callback handlerWCF:从客户端回调处理程序调用自托管服务
【发布时间】:2012-07-20 16:08:38
【问题描述】:

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

场景:

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

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

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

我尽量简化代码。我确实阅读了这篇文章,但我仍然找不到问题所在: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。

【问题讨论】:

    标签: wcf concurrency


    【解决方案1】:

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

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

    编辑

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

    • 为什么需要单实例模式?
    • 更改并发模式后是否更新了服务引用?

    【讨论】:

    • 嗯,当然是由于客户端出站调用...它在服务接口和客户端的回调行为中都被指定为可重入...那么,您有什么建议?跨度>
    • 服务必须是单例的——它可以被同一台机器上的多个客户端访问,并且服务中的状态/数据会反射回所有客户端。是的,服务参考已更新。它应该可以工作,因为 CallbackBehavior=Reentrant 应该使客户端能够在服务回调期间进行出站调用...
    • 那可能是你的问题。当这个单例服务需要等待 2 次回调时会发生什么?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-09-30
      • 1970-01-01
      • 2012-11-27
      • 2018-04-02
      • 1970-01-01
      • 2015-05-20
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多