Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading C#Win表单-使用后台工作程序时主线程没有响应_Multithreading_Winforms_Datagridview_C# 3.0_Backgroundworker - Fatal编程技术网

Multithreading C#Win表单-使用后台工作程序时主线程没有响应

Multithreading C#Win表单-使用后台工作程序时主线程没有响应,multithreading,winforms,datagridview,c#-3.0,backgroundworker,Multithreading,Winforms,Datagridview,C# 3.0,Backgroundworker,我有一个datagridview,它由一个数据表通过DataSource填充,我使用backgroundworker在datagridview中格式化单元格(单元格的背景色和前景色) BackgroundWorker bw = new BackgroundWorker(); private void Frm_Find_Load(object sender, EventArgs e) { bw.WorkerSupportsCancellation = true; bw.DoWork

我有一个datagridview,它由一个数据表通过DataSource填充,我使用backgroundworker在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();
    }
}
BackgroundWorker bw=新的BackgroundWorker();
私有void Frm_Find_Load(对象发送方,事件参数e)
{
bw.workersupport扫描单元=真;
bw.DoWork+=新DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(bw\u RunWorkerCompleted);
}
void bw_DoWork(对象发送方,DoWorkEventArgs e)
{
检查有效值();
}
公共bool checkforvalidvalue()
{
调用((MethodInvoker)委托()
{
对于(int i=0;iprogressBar1.Value++);
}
});
this.Invoke((MethodInvoker)委托()
{
BtnShow.Enabled=true;
dgv.Enabled=true;
});
}
私有void btnSave\u单击(对象发送方,事件参数e)
{
如果(bw.IsBusy==false)
{
progressBar1.Visible=true;
progressBar1.值=0;
BtnShow.Enabled=false;
dgv.Enabled=false;
progressBar1.Maximum=dgv.Rows.Count;
RunWorkerAsync();
}
}
当整个过程停止时,DataGridView仍保持
Enabled=false
,因此用户无法更改DataGridView中的任何值

datagridview中通常有15000行,要格式化的行太多,这需要时间,这就是为什么我使用backgroundworker,它工作得非常好,但是当用户尝试按几次启用的假datagridview时,主线程变得无响应,progressbar冻结


有谁能指导我如何处理它吗?

可能会尝试在单击按钮时禁用该按钮,直到完成任务为止

假设您的按钮名为Button1

当用户单击启用的假数据网格视图时,使用按钮。启用=假,然后在作业完成时使用按钮。启用=真


希望有帮助

您正在使用
Invoke
运行整个代码。这意味着您正在切换到UI线程,并且代码正在UI线程中运行。因为代码对于循环来说是一个耗时的
,所以它阻塞了UI线程

与其使用
BackgroundWorker
格式化单元格,不如使用事件:

private void dgv_CellFormatting(对象发送方,DataGridViewCellFormattingEventArgs e)
{
//如果这是标题单元格或新行,则不执行任何操作
如果(e.RowIndex<0 | | e.ColumnIndex<0 | | e.RowIndex==dgv.NewRowIndex)
返回;
//如果设置所需列的格式,请执行验证
if(e.ColumnIndex==dgv.Columns[“Name”].Index)
{
//在此处执行验证并更改单元格背面颜色。
}
}

为什么要使用C#3.0?升级并使用
async/await
@AluanHaddad我知道我使用的是Visual Studio(2008)的obselete版本,但由于某些原因,我不得不坚持使用它,你能告诉我一个itbutton gets enabled=false的解决方法吗?单击它的那一刻,直到整个工作完成(很抱歉,忘记在上面的代码中添加它)你能为它添加一个代码片段吗,因为我不知道在这种情况下如何使用它抱歉,但我无法理解“CellFormatting”将如何被调用,以及它将如何不像backgroundworker那样在UI线程中工作。我没有说CellFormatting将在不同的线程上运行。我刚才告诉过你为什么在你的方法中UI被阻塞了。我还向您展示了格式化单元格的更好方法。很抱歉,我现在没有使用此事件uptill,但是它将如何工作,因为我正在设置一个不会触发CellFormatting事件的数据源。此事件属于DataGridView。像处理任何其他事件一样处理它。我已经发布了该活动的MSDN页面链接。
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.
    }
}