2

UI から別のスレッドで実行時間の長いインスタンス メソッドを実行しようとしていますが、進行状況を GUI スレッドに報告して進行状況バーを更新しています。これを行うには多くの方法があり、これに関する SO に関する多くの質問があることは知っています。私が持っている長期実行インスタンス メソッドには、実際には独自の 2 つのイベントがあります。PropertyChanged で発生するイベントがあります。これは、完了した現在の作業と、完了する必要がある現在の合計作業を報告するためのものです。OperationCompleted イベントもあります。BackgroundWorkerUI で を使用して、この長時間実行されるメソッドを別のスレッドで実行することを計画していました。私が理解しようとしているのは、次のとおりです。

PropertyChanged イベントと OperationCompleted イベントのイベント ハンドラーを作成した場合、それらを実装してBackgroundWorkerイベントを発生させることはできますか? これにより、それらすべてがバックグラウンド スレッドで実行され、本質的に UI スレッドにバブリングするイベントをシミュレートできるようになりますか? 以下に例を示します。

class GUI : Form
{
     private BackgroundWorker back = new BackgroundWorker();
     back.WorkerReportsProgress = true;
     back.DoWork += new DoWorkEventHandler(myWork);
     back.ProgressChanged += new ProgressChangedEventHandler(myWork_changed);
     back.RunWorkerCompleted += RunWorkerCompletedEventHandler(myWork_completed);

     /* GUI CODE OMITTED */

     private void button_click(object sender, EventArgs e)
     {
          back.RunWorkerAsync();
     }
     private void myWork(object sender, DoWorkEventArgs e)
     {
          Syncer sync = new Syncer();
          sync.PropertyChanged += new PropertyChangedEventHandler(sync_PropertyChanged);
          sync.OperationCompleted += new EventHandler(sync_OperationCompleted);
          sync.LongRunningMethod();

     }
     private void sync_PropertyChanged(object sender, PropertyChangedEventArgs e)
     {
           //calculations & logic as needed
           back.ReportProgress(calculated);
     }
     //might not be necessary to implement because of how BackgroundWorker functions
     private void sync_OperationCompleted(object sender, EventArgs e)
     {
           back.ReportProgress(100);
     }

     private void myWork_changed(object sender, ProgressChangedEventArgs e)
     {
          //update UI progress bar
     }
     private void myWork_completed(object sender, RunWorkerCompletedEventArgs e)
     {
          //tasks needed @ completion such as hide progress bar
     }

では、Syncer クラスのイベントはBackgroundWorkerDoWork()メソッドと同じスレッドで発生するのでしょうか? このスレッドは安全ですか? 批判と代替提案を歓迎します!

4

2 に答える 2

1

バックグラウンド ワーカー スレッドから発生したイベントは、そのスレッドで実行されてブロックされます。また、BackgroundWorker への参照にアクセスできる限り、ワーカー スレッドで実行されてブロックされる ReportProgress イベントを発生させることもできます。

これを念頭に置き、invoke 呼び出しを使用して UI を更新すると、正常に動作するはずです。

于 2013-11-12T16:51:08.803 に答える