繁体   English   中英

C#Backgroundworker继续运行DoWork

[英]C# Backgroundworker keep on running DoWork

下面是我的编码:

    Form2 msgForm;
    private void button3_Click_1(object sender, EventArgs e)
    {

        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

        msgForm = new Form2();

        try
        {
            bw.RunWorkerAsync();

            msgForm.ShowDialog();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        // Coding that transmit protocol and will last around 2 minutes.
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        msgForm.Close();
    }

每当我单击一个按钮来传输持续约2分钟的协议时,我都会使用后台工作者方法。 在传输过程中,From2将显示“请稍候”。

但是我在使用这种编码时遇到了一些问题。 问题是,当我第一次单击该按钮时,它将传输一次协议。 之后,我再次单击第二次,它两次传输协议。 之后,我再次单击第三次,它发送了3次协议。...依此类推。 每次单击按钮,传输协议的次数都会增加。

每次单击按钮时,它只会在void bw_DoWork中的编码一次后运行吗?

我的编码有问题吗?

每次单击时,您都将附加一个附加处理程序,然后该处理程序将与之前添加的所有内容一起运行,并保持原样(因为该对象仍在此处,因此您将重新使用它)。

要解决此问题,您需要执行以下任一操作:

  • 将后台工作程序的声明移动到方法内(因此每次都是新的,只有一个DoWork处理程序

像这样:

private void button3_Click_1(object sender, EventArgs e)
{
    BackgroundWorker bw = new BackgroundWorker();
    // rest of your code
}
  • 移动.DoWork += ... ,它将处理程序追加到类的构造函数中

这主要取决于您是否在其他地方使用了该工作人员。

每次点击似乎都有一个新工作人员开始。 为避免此行为,请在再次启动之前检查工作人员是否忙碌。

try
{
    if (!bw.IsBusy)
        bw.RunWorkerAsync();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

并且您可以在backgroundworker进行工作时禁用该按钮,方法是button3.Enabled = false; 并在bw_RunWorkerCompleted方法中重新启用它,让用户理解他必须等待并且无法再次单击,直到该过程完成。

首先,在传输代码之前,请确保您的列表/收藏夹是清晰的。 然后在源代码中使用BreakPoint,并记住您的BackgroundWorker不能运行两次或多次,因为您使用ShowDialog。

检查工作人员是否忙:

    if (!bw.IsBusy)         
    bw.RunWorkerAsync(); 

我还将禁用该按钮,并在执行过程时将文本更改为“正在运行”。

使用bw_RunWorkerCompleted方法事件调用,然后重新启用按钮并更改文本。 此方法与UI在同一线程上运行,因此没有跨线程问题。

在您的设计上,为什么要显示另一张“请稍候”通知的表格? 我建议您在异步过程开始之前更新现有表单上的标签(这样就不会引起跨线程UI问题),或者如果您需要在之后进行更新,则可以使用以下命令:

lblNotify.Invoke(new Action(() => lblNotify.Text = @"Please wait"));

然后,以上内容将允许您在主线程上运行请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM