C#backgroundworker advice

时间:2017-03-29 09:46:44

标签: c# multithreading datagridview

我有一个背景工作者问题 - 我是线程新手所以我试图尽可能轻松地完成这项任务。

我的主要问题是最终用户只有.NET 4.0,所以我不能使用await / async,并且被告知BGW对我正在使用的框架来说是最好的。

我有一个带有gif动画的“Please Wait”表单,我想在填充datagridview时加载它。我需要以某种方式做一个检查,以确保它已完成填充以关闭“请等待”,但我有点卡住如何实现这一点。

    public void btnSearch_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
        Application.DoEvents();
        try
        {
            this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
            int RowC = TestDataTableDataGridView.RowCount;
            if (RowC == 0)
            {
                MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }
        catch (System.Exception exc)
        {
            MessageBox.Show
                (
                "Problem" +
                exc.Message, "An error has occured", MessageBoxButtons.OK, MessageBoxIcon.Warning
                );
        }
        finally
        {
            //pleaseWait.Close();
        }

这是我将数据加载到DataGridView的按钮。到目前为止,这是我的DoWork活动

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        pleaseWait.ShowDialog();
    }

由于交叉线程finally将无效(因此当前注释掉)但我需要进行循环/检查以确定DataGridView是否已填充并且操作已完成然后关闭{{ 1}}。或者有些人如何强迫它跳转到DoWork然后我可以在那里放一个RunWorkerCompleted

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您必须在主ui主题中显示pleaseWait对话框,而不是backgroundWorker1.DoWork,并将其隐藏在RunWorkerCompleted的{​​{1}}事件中。 this.TestDataTableAdapter.Fill是应该放在backgroundWorker1.DoWork中的部分,所以你的代码应该或多或少看起来像这样:

backgroundWorker1

当然,在此代码中您遇到了问题,因为public void btnSearch_Click(object sender, EventArgs e) { pleaseWait.ShowDialog(); backgroundWorker1.RunWorkerAsync(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime))))); } catch (System.Exception exc) { //You can't show a messagebox here,as it is not in the UI thread } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { pleaseWait.Close(); int RowC = TestDataTableDataGridView.RowCount; if (RowC == 0) { MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand); } } 代码无法正常运行,因为您尝试访问某些TestDataTableAdapter.Fill而您无法访问其他线程。

你有几个解决方案。您可以在调用backgroundworker之前使用一些变量来读取值,并访问此变量而不是TextBoxes。或者您可以使用参数调用backgroundworker。

我建议您详细了解TextBoxes,例如MSDN。或this question关于向BackGroundWorker发送参数。