私のアプリには、ピクチャボックスと2つのボタン(「はい」と「いいえ」)があります。はいは結果リストに 1 を追加し、いいえは 0 を追加して、両方とも次の画像に進みます。ここで、アプリにタイマーを実装して、答えが提供されない場合に画像を次に移動する必要があります。バックグラウンドワーカーを使用することを考えました。
以下のコードは、ボタンをクリックしないと写真をうまく切り替えます。ボタンをクリックすると、バックグラウンドワーカーが「ビジー」のままになるため、UI がフリーズします。CancelAsync がバックグラウンドワーカーをすぐに停止しないことは理解していますが、DoWork の return-statement が実際にヒットしています。
ここでの私の質問は、なぜバックグラウンドワーカーが忙しくしているのか、それとも私がここで完全に間違った方向に進んでいるのかということです.
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 の提案に従ってタイマーを使用してコードを変更しました。backgroundworker-question の詳細については、受け入れられた回答のコメントをお読みください。