所以现在我有一个方法可以调用三次不同的方法。
List<BackgroundWorker> bgws = new List<BackgroundWorker>();
AutoResetEvent _workerCompleted = new AutoResetEvent(false);
void methodA () {
methodB(); //bw1
methodB(); //bw2
methodB(); //bw3
//wait for the background workers that were kicked off above to finish
_workerCompleted.WaitOne();
Console.Writeline("hey");
}
void methodB() {
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bgws.Add(bw);
bw.DoWork += (sender, DoWorkEventArgs) => { bwWork(sender, DoWorkEventArgs, info); };
bw.ProgressChanged += (sender, ProgressChangedEventArgs) => { bwProgressChanged(sender, ProgressChangedEventArgs, info); };
bw.RunWorkerCompleted += (sender, RunWorkerCompletedEventArgs) => { bwCompleted(sender, RunWorkerCompletedEventArgs, info); };
bw.RunWorkerAsync();
}
bwWork
和bwProgressChanged
事件无关紧要。前者只是处理文件,后者正在更新进度条和标签。
private void bwCompleted(object senderr,
System.ComponentModel.RunWorkerCompletedEventArgs e, SenderInfo info)
{
BackgroundWorker bw = (BackgroundWorker)senderr;
Console.WriteLine(Path.GetFileName(info.path) + " : Finished.");
bgws.Remove(bw); //remove the bw from the list
//remove events from bw
bw.DoWork -= (sender, DoWorkEventArgs) => { bwWork(sender, DoWorkEventArgs, info); };
bw.ProgressChanged -= (sender, ProgressChangedEventArgs) => { bwProgressChanged(sender, ProgressChangedEventArgs, info); };
bw.RunWorkerCompleted -= (sender, RunWorkerCompletedEventArgs) => { bwCompleted(sender, RunWorkerCompletedEventArgs, info); };
//dispose bw
bw.Dispose();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
if (bgws.Count == 0) //if there are no more bw's, we're good to go
{
MessageBox.Show("Done.");
bgws.Clear();
_workerCompleted.Set();
}
}
所以最后,我希望所有后台工作人员在打印出“嘿”之前完成他们正在做的事情。我尝试使用AutoResetEvent和ManualResetEvent,但它们出现时似乎没有任何事情发生。我的意思是,当我把他们包括在内时,没有一个后台工作人员跑了。
我会调用一个帖子,但我有点不情愿,因为我被告知后台工作人员在进行后台工作和更新UI时会使用它。有什么方法可以让我等三个后台工作人员继续我的课程吗?
答案 0 :(得分:1)
我认为问题在于BackgroundWorker在单独的线程上执行DoWork
,但使用创建它的线程来运行ProgressChanged
和RunWorkerCompleted
事件,以便他们可以更新UI 。但是如果您已经将UI线程绑定在WaitOne
或其他旋转中,则无法执行这些事件。
在bwCompleted
bgws.Count == 0
时,为什么不打电话给methodA_AfterDone
来处理methodA
的阅读,然后methodA
结束SHOW VARIABLES LIKE '%wait%';
BW3?
答案 1 :(得分:0)
知道我迟到了两年,但这是我在类似情况下所做的。
创建一个完成的计数器。
每当列表中的BGW
完成时,就向完成的计数器添加1。
进行了单独的MonitorBGW
设置,并设置了while循环,如下所示。
While(CompletedCounter < ListBGWs.Count){Thead.Sleep(2000)}
//Put my code I wanted run after they all completed here.
希望这对某人有帮助:)
答案 2 :(得分:-1)
很简单,您不使用BackgroundWorker并切换到“任务”。 Task.Run(() => Your work );
在您这样做之后,您可以使用Task.WaitAll(task1,task2);
您可以切换任何EAP to Tasks。通过异步,您可以轻松完成此任务。