2009-07-18 1 views
1

私はWCFサービスの初心者です.WCFサービスを非同期に呼び出すときに、LabelコントロールのようなWPF UI要素を更新する方法があるかどうかを判断しようとしています。ここでDispatcherでUIエレメントを更新するより良い方法はありますか?

は、コードの一部です:あなたが見ることができるように

private void button1_Click(object sender, RoutedEventArgs e) 
    { 

     int result; 
     CalculatorServiceClient proxy = new CalculatorServiceClient(); 
     AsyncCallback addOperation = (async_result) => 
     { 
      result = proxy.EndAdd(async_result); 

      Dispatcher.Invoke(DispatcherPriority.Normal, 
        new Action(
         delegate() 
         { 
         label1.Content = result.ToString(); 
         } 
       ) 
      ); 
      proxy.Close(); 
     }; 
     proxy.BeginAdd(Convert.ToInt32(txtNumber1.Text), Convert.ToInt32(txtNumber2.Text), addOperation, null); 

    } 

、私はAsyncCallbackによって得られた非同期結果、とlabel1.Contentを更新しています。

私の質問は、この非同期コールバック操作内のUIコントロールをリフレッシュするためのより良い、またはより正しい方法がありますか?

ありがとうございます!

答えて

3

Dispatcher.Invokeは、UIを更新する良い方法です。 UIアクションはUIスレッドによって実行されなければなりません。ディスパッチャーはこれを処理します。

あなたは、ラムダ式を使用して、あなたのコードが少し短くすることができます。

Dispatcher.Invoke((Action<string>) ((data) => { label1.Content = data; })); 

それはそれになるだろうので、私はまた、使用する文でプロキシを置くことをお勧め:

int result = 0; 
using (CalculatorServiceClient proxy = new CalculatorServiceClient()) { 
    AsyncCallback callback = new AsyncCallback((asyncResult) => { 
     result = proxy.EndAdd(asyncResult); 
     Dispatcher.Invoke((Action<string>) ((data) => { label1.Content = data; })); 
    }); 

    proxy.BeginAdd(Convert.ToInt32(txtNumber1.Text), Convert.ToInt32(txtNumber2.Text), callback, null); 
} 

かあなたがそれが好きなら、短い:

int result = 0; 
using (CalculatorServiceClient proxy = new CalculatorServiceClient()) 
    proxy.BeginAdd(Convert.ToInt32(txtNumber1.Text), Convert.ToInt32(txtNumber2.Text), new AsyncCallback((asyncResult) => { 
     result = proxy.EndAdd(asyncResult); 
     Dispatcher.Invoke((Action<string>) ((data) => { label1.Content = data; })); 
    }), null); 
+0

実際には、WCFは私がどこで 'using'ブロックを実装すべきか知っている1つのケースです。 http://weblogs.asp.net/jezell/archive/2008/07/02/indisposable-wcf-gotcha-1.aspxの「Indisposable:WCF Gotcha#1 - Jesse Ezell Blog」を参照してください。 –

+0

うわー、でも分かりますか? Closeメソッドをまったく使用しないでくださいが、Abort()メソッドを使用するべきですか?これは実際には特定の問題を使用するのではなく、マイクロソフトによるより奇妙な実装です。 – Zyphrax

+1

いいえ、閉じるはOKです。問題は次のとおりです。「使用」で例外1がスローされました。 Disposeが呼び出されます。コールを「閉じる」;クローズスロー例外2.例外1が失われました。私が投稿したブログのパターンが動作します。そして、はい、それはマイクロソフトの悪いデザインです。彼らは1つを逃した。私はDon Boxの見積もりを見つけました。このシナリオで呼び出されたときにクローズがスローされても問題ないかどうか尋ねられました。彼はすでに例外を処理していたのでOKでした。彼は_different_例外を処理していたことを忘れていました。 –

1

さらに短くすることができます:

using (var proxy = new CalculatorServiceClient()) 
{ 
    proxy.BeginAdd(
     Convert.ToInt32(txtNumber1.Text), 
     Convert.ToInt32(txtNumber2.Text), 
     (asyncResult) => 
      { 
       int result = proxy.EndAdd(asyncResult); 
       Dispatcher.BeginInvoke(
        (Action)() => { label1.Content = result; }); 
      }, 
     null); 
} 

トリックは、Invoke/BeginInvokeは、パラメータを明示的に渡す必要があるとは限りません。

Invokeを使用したくない場合は、バックグラウンドスレッドを不要にするためです。

関連する問題