在处理形式之前停止背景工作者的正确方法

时间:2014-07-08 11:46:43

标签: c# forms backgroundworker

在我的应用程序中,我使用子表单,用户必须将一些数据填入文本框,然后单击“确定”或“取消”。为了防止使用空字段,我想使用一个后台工作程序来监视字段并保持“确定”按钮被禁用,直到填满所有字段。代码(几乎)工作但在子窗体处理时抛出异常,可能是因为bgw仍在运行但表单已经处理掉了。我怎样才能正确阻止bgw?

    private void FormRecSettings_Load(object sender, EventArgs e)
    {
        this.tb_recdatetime.Text = DateTime.Today.ToString("yyyyMMdd") + "_";

        backgroundWorker2.WorkerSupportsCancellation = true;
        backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);


        btn_ok.Enabled = false;
        if (backgroundWorker2.IsBusy != true)
        {
            backgroundWorker2.RunWorkerAsync();
        }
    }

    void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
       while(true)
       {
            if ((backgroundWorker2.CancellationPending == true))
            {
                e.Cancel = true;
            }


            if (tb_recsuffix.Text.Length > 0 && tb_filename.Text.Length > 0)
                SetControlPropertyThreadSafe(btn_ok, "Enabled", true);

            else SetControlPropertyThreadSafe(btn_ok, "Enabled", false);
        }

    }


    public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
    {
        if (control.InvokeRequired)
        {
            control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
        }
        else
        {
            control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
        }
    }

    private void btn_ok_Click(object sender, EventArgs e)
    {

        if (backgroundWorker2.WorkerSupportsCancellation == true)
        {
            backgroundWorker2.CancelAsync();
        }


        string mm, inv;

        if (rbtn_UK.Checked == true) mm = "UK";
        else mm = "DE";

        if (rbtn_invyes.Checked == true) inv = "Yes";
        else inv = "No";

        // instance the event args and pass it each value
        NewRecUpdateEventArgs args = new NewRecUpdateEventArgs(tb_recsuffix.Text, tb_filename.Text, mm,
                                                                    inv);

        // raise the event with the updated arguments

        NewRecUpdated(this, args);

        this.Dispose();
    }

2 个答案:

答案 0 :(得分:1)

很抱歉地说,但在我看来,BackgroundWorker有点矫枉过正,可能会给你带来更多问题,然后快乐。

我建议连接TextChanged的{​​{1}}事件并检查是否可以启用按钮。

TextBox

事件处理程序:

foreach (Control c in this.Controls)
{
    if (c is TextBox)
    {
        c.TextChanged += tb_TextChanged;
    }
}

答案 1 :(得分:0)

根据Patrick的提示更新了我的doWork功能,现在看起来工作正常(见下文)。但是,Patrick的基于事件的textchanged解决方案更好。

    void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            if ((backgroundWorker2.CancellationPending == true))
            {
                e.Cancel = true;
            }

            if (!this.IsDisposed || this.Disposing)
            {
                if (tb_recsuffix.Text.Length > 0 && tb_filename.Text.Length > 0)
                    SetControlPropertyThreadSafe(btn_ok, "Enabled", true);

                else SetControlPropertyThreadSafe(btn_ok, "Enabled", false);
            }

            Thread.Sleep(500);

        }

    }