C# 是否使用BackgroundWorker更新GUI中的两个(单个操作/总操作)进度条?

C# 是否使用BackgroundWorker更新GUI中的两个(单个操作/总操作)进度条?,c#,multithreading,C#,Multithreading,好吧,我一整天都在用头撞这个。我还是一个编程新手,很可能我的整个方法都被误导了。但无论如何……我有一个简单的gui应用程序,它有一个充满文件夹的列表框,我正在按顺序对每个文件夹中的每个文件执行一个操作。这是一个很长的操作,所以我有两个进度条-每个文件一个,每个文件夹一个 private void buttonApplySelected_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } pr

好吧,我一整天都在用头撞这个。我还是一个编程新手,很可能我的整个方法都被误导了。但无论如何……我有一个简单的gui应用程序,它有一个充满文件夹的列表框,我正在按顺序对每个文件夹中的每个文件执行一个操作。这是一个很长的操作,所以我有两个进度条-每个文件一个,每个文件夹一个

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循环时更新一次,但它给我的
跨线程操作无效:控件“folderProgressBar”是从创建它的线程以外的线程访问的。

如果我把它移出for循环,它在每个文件夹之后都不会更新。 如果我将所有UI更新移出DoWork函数,并在for循环中调用DoWork函数,那么显然不会等待每个文件夹完成,我会得到“worker仍在忙”异常


有什么想法吗?

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);