在我的应用程序中,我有一个图片框和2个按钮(“是”和“否”)。是将1添加到结果列表中,不添加0并且都转到下一张图片。 现在我需要在应用程序中实现一个计时器,如果没有提供答案,图片将转到下一个计时器。我想为它使用背景工作。Backgroundworker保持忙碌
下面的代码可以在我不点击按钮时切换图片。点击一个按钮会冻结UI,因为背景工作者保持“忙碌”状态。 我明白,CancelAsync不会立即停止backgroundworker,但DoWork中的返回语句实际上被打了。
所以我在这里的问题是为什么backgroundworker保持忙碌或者我完全在这里错误的方式?
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Counter = 0;
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += _backgroundWorker_DoWork;
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.RunWorkerAsync();
}
private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = sender as BackgroundWorker;
GoToNextItem(); //Show next picture
while (!bgw.CancellationPending)
{
_getNext = false;
Stopwatch sw = Stopwatch.StartNew();
//Wait interval-time
while (!_getNext)
{
if ((sw.ElapsedMilliseconds > Test.Interval * 1000) && !bgw.CancellationPending)
{
_getNext = true;
}
if (bgw.CancellationPending)
{
e.Cancel = true;
return; //Breakpoint is hit here
}
}
if (_getNext)
{
Result.Add(0);
GoToNextItem();
}
}
e.Cancel = true;
}
private void btnNo_Click(object sender, EventArgs e)
{
_backgroundWorker.CancelAsync();
Result.Add(0);
while (_backgroundWorker.IsBusy)
{
_backgroundWorker.CancelAsync();
System.Threading.Thread.Sleep(20);
}
_backgroundWorker.RunWorkerAsync();
}
private void btnYes_Click(object sender, EventArgs e)
{
_backgroundWorker.CancelAsync();
Result.Add(1);
while (_backgroundWorker.IsBusy) //Stays busy ==> UI freezes here
{
_backgroundWorker.CancelAsync();
System.Threading.Thread.Sleep(20);
}
_backgroundWorker.RunWorkerAsync();
}
编辑
通过使用定时器由@Servy所建议的改变的代码。 欲了解关于背景问题的更多细节,请阅读已接受答案的评论。
似乎可以更改我的代码。谢谢。这将解决我的问题,但是我仍然想知道为什么即使退出Do_Work,BGW仍然处于忙碌状态。我刚刚测试了另一种方法,通过执行_BackgroundWorker = new BackgroundWorker,添加事件并调用RunAsync。而这实际上工作。 – Koen
@Koen正如我在我的回答中解释的,问题不在于'DoWork',问题在于你的按钮处理程序在等待GBW完成时正在休眠,这就是阻止UI的原因。 – Servy
对不起,没有完全理解它,但在阅读@ JYelton的帖子后。我知道了。我当时的印象是退出DoWork完成BGW。 – Koen