2016-10-25 4 views
0

サービスで実行された各アクションの後にクライアントにメッセージを送信するWCFサービスの実行中に、自分のWPF UIを更新する際に問題があります。 WSDualHttpBindingを使用します。 サービスからの各メッセージのメッセージボックスを表示すると、同じ実装が完全に機能します。しかし、これはUIの更新では機能しません。WCFコールバックメッセージでWPF UIに通知する

PS:私はMVVMパターンを使用し、Caliburn.micro 私の実装を簡素化:

1-インタフェース:

public interface IMyContractCallback 
{ 
    [OperationContract] 
    void OnCallback(); 
} 


[ServiceContract(CallbackContract = typeof(IMyContractCallback))] 
public interface IMyContract 
{ 
    [OperationContract] 
    void DoSomething(); 
} 

2-サービス:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)] 
public class MyService : IMyContract 
{ 
    public void DoSomething() 
    { 
     DoJob1(); 
     var callbackChannel = OperationContext.Current.GetCallbackChannel<IMyContractCallback>(); 
     callbackChannel.OnCallback(); 
     DoJob2(); 

    } 
} 

3-クライアント:

  • コールバックの実装:

パブリックデリゲートvoid ClientNotifiedEventHandler(Object sender、ClientNotifiedEventArgs e);

public class ClientNotifiedEventArgs : EventArgs 
    { 
       private readonly string _message; 
       public string Message { get { return _message; } } 

       public ClientNotifiedEventArgs(string message) 
       { 
        this._message = message; 
       } 
    } 



    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)] 
     public class MyCallbackClient : IMyContractCallback 
     { 
public event ClientNotifiedEventHandler ClientNotified; 
      public void OnCallback() 
      { 
       if (ClientNotified != null) 
         { 
          ClientNotified(this, new ClientNotifiedEventArgs(log)); 
         } 
      } 
     } 
  1. ビューモデルの実装:

    パブリッククラスMyViewModel {

    private string _message = "Loading.."; 
    
        public string MessageLog 
    
        { 
         get { return _message; } 
         set 
         { 
          _message = value; 
          NotifyOfPropertyChange(() => MessageLog); 
         } 
        } 
    
        public void DoTheJob() 
        { 
         var callback = new DbLoaderCallback(); 
         callback.ClientNotified += Callback_ClientNotified; 
         var context = new InstanceContext(callback); 
         using (var serviceClient = new MyService(context)) 
         { 
          serviceClient.DoSomething(); 
         } 
        } 
    
        private void Callback_ClientNotified(object sender, ClientNotifiedEventArgs e) 
        { 
         MessageLog += " \n"; 
         MessageLog += e.Message; 
    
        }  
    

    }ここ

、実行callbackChannel.OnCallback(に来ます)。 (MyService上)、NotifyOfPropertyChange()=> MessageLogに来ると、MyViewModel上のクライアントに行きます。実行を継続しません。だからDoJob2()は決して実行されませんでした。

問題を正確に見ている人はいましたか? ありがとうございます

答えて

0

コールバックにはUseSynchronizationContext = falseが指定されています。つまり、すべてのコールバックがスレッドプールで呼び出されます。 UIは、スレッドをディスパッチャーから更新することはできません。したがって、MessageLogプロパティの更新をディスパッチャスレッドにマーシャリングする必要があります。 this answerを参照してください。

関連する問題