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();

    }

}

サービスは Duplex です - 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 に答える