2016-04-17 7 views
3

ええ、私はこの一日中、頭を叩いています。私はまだかなりプログラミングの新人です、そして、私のアプローチ全体が間違っている可能性がかなりあります。しかし、とにかく...私はフォルダの完全なリストボックスを持つ単純なGUIアプリケーションを持って、私は順次各フォルダ内のすべてのファイルに対して操作を実行しています。これは非常に長い操作ですので、各ファイルに1つずつ、各フォルダに1つずつ、2つのプログレスバーがあります。BackgroundWorkerを使用してGUIで2つ(個々の操作/合計操作)の進捗バーを更新しますか?

private void buttonApplySelected_Click(object sender, EventArgs e) 
{ 
    backgroundWorker1.RunWorkerAsync(); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    double percentToIncrement = 100.0/Convert.ToDouble(selectedDirList.Count); 
    double percentComplete = percentToIncrement; 
    folderProgressBar.Value = 0; 
    foreach (string dir in selectedDirList) 
    { 
      engine = new OEngine.OEngine(dir, backgroundWorker1); 
      engine.ProcessSelected(processType); 

      int percentCompleteInt = Convert.ToInt32(percentComplete); 
      folderProgressBar.Value = percentCompleteInt; 
      percentComplete += percentToIncrement; 
    }   
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    fileProgressBar.Value = e.ProgressPercentage; 
} 

BackgroundWorker自体がエンジンに渡され、そのフォルダーを処理するエンジンのコード内で進行状況が更新されます。 (これはおそらく私の最初の間違いです。)UIはProgressChangedイベントをキャッチし、自身のスレッド内でfileProgressBarを更新します。

しかしfolderProgressBarは、すべてのforループを通過する度に更新する必要がありますが、それは私がのためにループの外に移動した場合、それは各フォルダの後に更新文句を言わない私にCross-thread operation not valid: Control 'folderProgressBar' accessed from a thread other than the thread it was created on.

を与えます。 DoWork関数からすべてのUI更新を移動し、代わりにforループでDoWork関数を呼び出すと、明らかに各フォルダが終了するのを待たずに「ワーカーはまだビジー状態です」という例外が発生します。

アイデア?

答えて

-1

Windowsフォームのための一般的な解決策: 使用

WindowsFormsSynchronizationContext syncContext = new WindowsFormsSynchronizationContext(); 

...

//in the background work or any non UI Thread 

//Trigger an update in the GUI thread; one can also use syncContext.Send (depending on the need for syncrhonous or async operation) 
syncContext.Post(UpdateGUI, userData); 

... 

void UpdateGUI(object userData) 
{ 
    //update your progress bar 
} 
If using wpf, declare a variable syncContex. 
SynchronizationContext syncContext; 
//And when in the UI thread, set the variable's value as 
syncContext = SynchronizationContext.Current; 

//Then from the non-UI thread, 
syncContext.Post(UpdateGUI, userData); 
+0

私は完全にコードの各ブロック以下のいませんよ行く。 –

関連する問題