【发布时间】:2017-06-06 20:09:34
【问题描述】:
所以现在我有一个方法可以调用 3 次不同的方法。
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 时使用的东西。有什么方法可以让我等待三个后台工作人员,以便我可以继续执行我的程序?
【问题讨论】:
-
您是否无法让后台工作人员实际执行任务,或者您是否无法与所有工作人员同步并检测所有工作何时完成?我不清楚你具体遇到了什么问题。
-
很抱歉。所以如果我在程序中包含
AutoResetEvent部分,后台工作人员都不会做任何事情。如果我不包括它,后台工作人员工作得很好,但Console.WriteLine("hey");是在工作人员完成他们正在做的事情之前执行的。我想我可以在检查后台工作人员列表是否为空的部分中添加更多代码,但是我还有更多代码要做,而且我觉得这会扰乱程序的流程。我只想让后台工作人员做他们的事情,然后继续处理 writeline 语句所在的位置。 -
澄清:后台工作人员不做任何事情(即
bwWork永远不会被执行),或者他们做他们的工作,但从不发出完全完成的信号,所以你的代码永远等待? -
您似乎在
bwCompleted中做了一些不必要的工作 - 为什么要在您即将访问对象的Dispose时删除事件?为什么Clear()bgws列表你已经清楚了? -
有趣。我很高兴你指出了这一点。
bwWork是当AutoResetEvent部分在程序中时执行的三个事件中的唯一一个。由于某种原因,进度没有改变,完成的事件也没有被执行。
标签: c# multithreading backgroundworker