0

デッドロックが発生することなく、コールバック内から 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 です。

ところで、DispatchIfNecessary は次のように実装されます。

public void DispatchIfNecessary(Action action)
        {
            if (!Dispatcher.CheckAccess())
                Dispatcher.Invoke(action);
            else
                action.Invoke();
        }
4

1 に答える 1

0

DispatchIfNecessaryの非同期バージョンを使用しInvokeているため、コールバックは UI の変更の終了を待機しません。これは、UI スレッドがコールバック処理の終了を待機しているため実行できません (したがって、デッドロックが発生します) 。

Dispatcher.BeginInvoke(action);
于 2013-11-12T09:03:06.720 に答える