C#Win Form - 使用后台工作程序时主线程无响应

时间:2017-05-14 06:38:45

标签: multithreading winforms datagridview c#-3.0 backgroundworker

我有一个 datagridview ,它由DataTable通过 DataSource 填充,我使用 backgroundworker 来格式化单元格(背面颜色) datagridview中的单元格和前景色。

body {
    background: url(https://unsplash.com/?photo=vZlTg_McCDo);
    background-size: cover;
}


#content {
    text-align: center;
    padding-top: 25%;
}

当整个过程发生故障时,DataGridView仍为BackgroundWorker bw = new BackgroundWorker(); private void Frm_Find_Load(object sender, EventArgs e) { bw.WorkerSupportsCancellation = true; bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); } void bw_DoWork(object sender, DoWorkEventArgs e) { CheckForValidValues(); } public bool CheckForValidValues() { dgv.Invoke((MethodInvoker)delegate() { for (int i = 0; i < Dt.Rows.Count; i++) { if (Dt.Rows[0]["Name"].ToString() == Value) { dgv.Rows[i].Cells["Name"].Style.BackColor = Color.FromArgb(255, 192, 192); } else { dgv.Rows[i].Cells["Name"].Style.BackColor = Color.White; } progressBar1.Invoke((MethodInvoker)(() => progressBar1.Value++)); } }); this.Invoke((MethodInvoker)delegate() { BtnShow.Enabled = true; dgv.Enabled = true; }); } private void btnSave_Click(object sender, EventArgs e) { if (bw.IsBusy == false) { progressBar1.Visible = true; progressBar1.Value = 0; BtnShow.Enabled = false; dgv.Enabled = false; progressBar1.Maximum = dgv.Rows.Count; bw.RunWorkerAsync(); } } ,因此用户无法更改datagridview中的任何值。

datagridview中通常有15,000行,并且要格式化很多行,这需要时间,这就是为什么我使用backgroundworker并且它可以正常工作完全正常但是当用户尝试按下时 启用false datagridview 几次,主线程无响应,进度条冻结。

任何人都可以指导我如何处理它吗?

2 个答案:

答案 0 :(得分:1)

您正在使用Invoke运行整个代码。这意味着您正在切换到UI线程,并且代码在UI线程中运行。由于代码是一个耗时的for循环,因此它阻止了UI线程。

不是使用BackgroundWorker来格式化单元格,而是使用CellFormatting事件更好:

private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    //If this is header cell or new row, do nothing
    if (e.RowIndex < 0 || e.ColumnIndex < 0 || e.RowIndex == dgv.NewRowIndex)
        return;

    //If formatting your desired column, perform validation
    if (e.ColumnIndex == dgv.Columns["Name"].Index)
    {
        // Perform validation and change cell back color here.
    }
}

答案 1 :(得分:0)

也许在点击工作完成后尝试禁用Button?。

假设您的Button名称是Button1,

当用户点击启用虚假数据网格视图时,使用Button.enabled = false,然后当作业完成时使用Button.enabled = true

希望有所帮助!