2017-04-06 3 views
-2

クラスライブラリ内のオブジェクトのBackgroundWorkerによって実行された作業の進捗状況を報告するにはどうすればよいですか?BackgroundWorkerを使用しているときにクラスライブラリで実行された作業の進捗状況を報告する方法

ReportProgressを使用して情報をフィードバックする方法(循環依存のため、呼び出し元のクラスを参照できない)はこれまでのところ分かりません。

これは、作業を開始し、メインプロジェクトの例です:

namespace MainProject { 
    class MainWindowVM : INotifyPropertyChanged { 
     private BackgroundWorker _counterWorker; 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     private int _progress; 
     public int Progress { 
      get { return _progress; } 
      set { _progress = value; NotifyPropertyChanged(); } 
     } 

     public MainWindowVM() { 
      var heavyWorker = new ClassLibrary.HeavyWorkerClass(); 
      _counterWorker = new BackgroundWorker(); 
      _counterWorker.DoWork += new DoWorkEventHandler(_counterWorker_DoWork); 
      _counterWorker.RunWorkerAsync(heavyWorker); 

     } 

     private void _counterWorker_DoWork(object sender, DoWorkEventArgs e) { 
      var heavyWorker = (ClassLibrary.HeavyWorkerClass)e.Argument; 
      heavyWorker.StartWork(); 
      Progress = 100; 
      System.Windows.MessageBox.Show("Work completed!"); 
     } 
    } 
} 

そしてここでは、クラスライブラリのアップロード方法の一例です:

namespace ClassLibrary { 
    public class HeavyWorkerClass { 
     public void StartWork() { 
      for (int i = 0; i <= 100; i++) { 
       Thread.Sleep(50); 
      } 
     } 
    } 
} 
+1

は 'ReportProgress'メソッドに見てみますか? [there](https://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners)は、これに関する多くのチュートリアルの1つです – lena

+2

あなたが何か問題があることを明確に示す良い[mcve]がなければどのような回答が必要かを知ることはできません(回答を投稿する人は、単に推測するだけで、実際のビジネスはありません)。 WPFプログラムを「普通に」書くと、UIオブジェクトにバインドされた 'INotifyPropertyChanged'を実装するビューモデルがあり、必要に応じてビューモデルのプロパティ値を設定できます。 WPFはあなたのためにすべてのクロススレッドのものを処理します。通常の方法でWPFを書いていない場合、それはより複雑になりますが、MCVEがなければ、正確な詳細は異なります。 –

+0

[BackgroundWorkerを使用してGUIを更新する]の複製があります(http://stackoverflow.com/questions/5192169/update-gui-using-backgroundworker) –

答えて

1

HeavyWorkerClassは、その進捗状況を報告しなければなりませんどういうわけか。そうでなければ、あなたは進歩について何も知っていないはずです。

たとえば、定期的にイベントを発生させることができます。ビューモデルはこのイベントにサブスクライブし、それに応じてProgressプロパティを更新することができます。ビューは、ビューモデルのProgressプロパティにバインドされます。

サービスやクラスライブラリのメソッドでは、その進行状況を報告するのはかなり珍しいことに注意してください。これは、ほとんどの場合、飛行中の操作の現在の進行状況を明らかにするAPIがないためです。このような状況では、同様の操作が完了するまでUIで同様の中間ProgressBarかを表示するように選択することがあります:

<ProgressBar IsIndeterminate="True" /> 
+0

ああ、もちろん! ProgressプロパティをHeavyWorkerClassの内部に移動し、INotifyPropertyChangedも実装することができます。 MainWindowVM内のHeavyWorkerClassオブジェクトのpublic getプロパティも追加すると、HeavyWorkerClass内のProgressプロパティにViewを直接バインドできます。ヒントありがとう! – Oystein

+0

サイドノートでは、(1)プロセスの実行時間が大きく異なり、(2)不確定でないため、IsIndeterminateを使用したくありません。 – Oystein

0

mm8のソリューションに続き、ここで更新されたコードです。作業を開始する

メインプロジェクト:時間のかかる作業を行い

namespace MainProject { 
    class MainWindowVM : INotifyPropertyChanged { 
     private BackgroundWorker _counterWorker; 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     private ClassLibrary.HeavyWorkerClass _heavyWorker; 
     public ClassLibrary.HeavyWorkerClass HeavyWorker { 
      get { return _heavyWorker; } 
     } 

     public MainWindowVM() { 
      _heavyWorker = new ClassLibrary.HeavyWorkerClass(); 
      _counterWorker = new BackgroundWorker(); 
      _counterWorker.DoWork += new DoWorkEventHandler(_counterWorker_DoWork); 
      _counterWorker.RunWorkerAsync(_heavyWorker); 
     } 

     private void _counterWorker_DoWork(object sender, DoWorkEventArgs e) { 
      var heavyWorker = (ClassLibrary.HeavyWorkerClass)e.Argument; 
      heavyWorker.StartWork(); 
      System.Windows.MessageBox.Show("Work completed!"); 
     } 
    } 
} 

HeavyWorkerClass:

namespace ClassLibrary { 
    public class HeavyWorkerClass : INotifyPropertyChanged { 

     private int _progress; 
     public int Progress { 
      get { return _progress; } 
      set { 
       _progress = value; 
       NotifyPropertyChanged(); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     public void StartWork() { 
      for (int i = 0; i <= 100; i++) { 
       Progress = i; 
       Thread.Sleep(50); 
      } 
     } 
    } 
} 
関連する問題