C#BackgroundWorker - 我应该如何摆脱DoEvents

poc*_*oco 1 c# backgroundworker doevents

我正在试图找出处理单击按钮点击触发的后台工作人员的最佳方法.我用3个单选按钮和一个标签创建了一个非常简单的表单.每个单选按钮共享相同的事件radioButton_CheckedChanged.如果事件完成,那么我将标签更新为"完成".如果在事件完成之前单击另一个单选按钮,则将标签更新为已取消.下面是我在这个快速示例中编写的代码.尽管应用程序倾向于按预期运行,但我关注的是使用Application.DoEvents.我有什么替代方案.出于显而易见的原因,我在IsBusy时无法入睡.我是否认为这一切都错了,或者有更好的方法吗?谢谢,poco

private void radioButton_CheckedChanged(object sender, EventArgs e)
{
  RadioButton rb = sender as RadioButton;
            if (rb.Checked)
            {
                if (backgroundWorker1.IsBusy)
                {
                    backgroundWorker1.CancelAsync();
                    while (backgroundWorker1.IsBusy)
                        Application.DoEvents();
                }

                backgroundWorker1.RunWorkerAsync();
            }
        }

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100 && !worker.CancellationPending; ++i)
                Thread.Sleep(1);

            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                label1.Text = "Canceled";
            else
                label1.Text = "Complete";
        }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 7

您应该将BackgroundWorker完成时必须运行的代码移动到RunWorkerCompleted hander中.在伪代码中:

private void radioButton_CheckedChanged(object sender, EventArgs e)
{
    // ...

    if (backgroundWorker1.IsBusy)
    {
        backgroundWorker1.CancelAsync();
        addJobToQueue();   // Don't wait here, just store what needs to be executed.
    } else {
        backgroundWorker1.RunWorkerAsync();
    } 
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled) {
        label1.Text = "Canceled";
    }
    else {
        label1.Text = "Complete";
    }

    // We've finished! See if there is more to do...
    if (thereIsAnotherJobInTheQueue())
    {
         startAnotherBackgroundWorkerTask();
    }
}
Run Code Online (Sandbox Code Playgroud)