2

私は2つのスレッドを持っています。

スレッド 1: WPF スレッド。すべての情報を含むウィンドウを表示します。
スレッド 2: 絶えずループし、情報を受け取り、スレッド 1 でウィンドウを更新します。

私は次のインターフェースを持っています。

IModuleWindow
{
    void AddModule(IModule module);
    void RemoveModule(IModule module);
}

IModule
{
    UserControl GetSmallScreen();
    UserControl GetBigScreen();
}

IModuleWindow は、スレッド 1 の WPF ウィンドウによって実装されます
。IModule はオブジェクトによって実装され、スレッド 2 でインスタンス化され、スレッド 1 に送信されます。

IModule の UserControls をスレッド 1 の Window オブジェクトに追加して表示したいと考えています。IModule オブジェクトはスレッド 2 で常に更新され、テキストを変更する必要があります。

基本的には、このプログラムはスレッド 2 内のオブジェクトの状態を表示することになっており、スレッド 2 は常に更新されます。

WPFでこれを達成する最良の方法は何ですか?

4

3 に答える 3

2

IMO の最良のアイデアは、非常に便利なメソッドとイベントでBackgroundWorkerを使用することです。ReportProgressProgressChanged

このProgressChangedイベントは GUI スレッドで発生するため、GUI の更新を直接実行できます。コードは次のようになります。

// initialize the worker
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();


// thread 2 (BackgroundWorker) 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // main loop
    while(true) 
    {
        // time-consuming work
        // raise the event; use the state object to pass any information you need
        ReportProgress(0, state);
    }
}

// this code will run on the GUI thread
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // get your state back
    object state = e.UserState;
    // update GUI with state
}
于 2012-08-27T10:02:00.723 に答える
1

別のスレッドで作成されたコントロールを使用できると便利です。それが私が理想的に望んでいることです。

簡単な答え:それを忘れてください。

UIコントロールは、単一のUIスレッドにのみ属します。ここでできる最善のことは、メインスレッドでコントロールを作成し、バックグラウンドスレッドでデータを準備し、メイン(UI)スレッドでコントロールのプロパティを再度更新することです。

データの準備には、TPLの使用をお勧めします。

于 2012-08-27T10:45:18.347 に答える
1

私が何をしなければならないかを理解するのにとても役立ちました。

シナリオは次のようにする必要があります。

ObservableCollection images = new ObservableCollection();
TaskFactory tFactory = new TaskFactory();

tFactory.StartNew(() =>
{
  for (int i = 0; i < 50; i++)
  {
    //GET IMAGE Path FROM SERVER
    System.Windows.Application.Current.Dispatcher
          .BeginInvoke((Action)delegate()
          {
            // UPDATE PROGRESS BAR IN UI
          });

     images.Add(("");
   }    
  }).ContinueWith(t =>
     {
       if (t.IsFaulted)
       {
          // EXCEPTION IF THREAD IS FAULT
          throw t.Exception;
        }
      System.Windows.Application.Current.Dispatcher
       .BeginInvoke((Action)delegate()
       {
          //PROCESS IMAGES AND DISPLAY
       });
    });

WPF で UI を更新するには、System.Windows.Application.Current.Dispatcher.BeginInvoke()を使用する必要があります。

于 2012-08-27T09:52:38.437 に答える