如何使用按钮启动和停止连续运行的后台工作者
假设我有一个像这样的后台工作者:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(true) { //Kill zombies } }
如何让这个后台工作者开始和停止使用WinForm上的按钮?
这是怎么做的(链接到下面的答案)
也许你可以使用像这样的手动重复测试,我没有调试这个,但值得一试。 如果它有效,你就不会让它在等待的时候旋转它的轮子
ManualResetEvent run = new ManualResetEvent(true); private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(run.WaitOne()) { //Kill zombies } } private void War() { run.Set(); } private void Peace() { run.Reset(); }
使用CancelAsync方法。
backgroundworker1.CancelAsync();
在你的工作线程里面的循环中。
if (backgroundWorker.CancellationPending) return;
这不会立即发生。
停止你真的意味着停止或你的意思是停顿? 如果你的意思是停止,那么这是小菜一碟。 为要负责启动后台工作程序的按钮创建按钮单击事件处理程序,并为负责停止后台工作程序的按钮单击事件处理程序创建。 在开始按钮上,调用触发do_work事件的后台工作方法。 像这样的东西:
private void startButton_Click(System.Object sender, System.EventArgs e) { // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(); }
在您的停止按钮上,调用将后台工作程序的CancellationPending
为true的方法,如下所示:
private void cancelAsyncButton_Click(System.Object sender, System.EventArgs e) { // Cancel the asynchronous operation. this.backgroundWorker1.CancelAsync(); }
现在不要忘记检查后台工作者的doWork中的CancelationPending
标志。 像这样的东西:
private void KillZombies(BackgroundWorker worker, DoWorkEventArgs e) { while (true) { if (worker.CancellationPending) { e.Cancel = true; } } }
你的doWork方法:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; KillZombies(worker, e); }
我希望这可以引导你朝着正确的方向前进。 一些进一步的阅读:
http://msdn.microsoft.com/en-us/library/b2zk6580(v=VS.90).aspx
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
我没有对此进行过测试,我在某个地方有代码,我必须要看到我做了什么,但这样的事情是对Fredrik的答案的改编:
private bool _performKilling; private object _lockObject = new object(); private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while(true) { if (_performKilling) { //Kill zombies } else { //We pause until we are woken up so as not to consume cycles Monitor.Wait(_lockObject); } } } private void StartKilling() { _performKilling = true; Monitor.Pulse(_lockObject); } private void StopAllThatKilling() { _performKilling = false; ]
这里有更完整的模式示例: