Agent_Spock
Agent_Spock

Reputation: 1187

C# Win Form - Main thread not responding when using background worker

I have a datagridview which is being populated by a DataTable through DataSource and i am using a backgroundworker for formatting of cells (back color and forecolor of cells) in 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();
    }
}

while the whole process goes down the DataGridView remains Enabled=false so that user cant change any values in datagridview.

There is usually 15,000 rows in the datagridview and that many rows to format, this takes time that is why I use a backgroundworker for it and it works perfectly fine BUT when the user tries to press the enabled false datagridview couple of times, the main thread becomes unresponsive and the progressbar freezes.

Can anyone guide me how to deal with it?

Upvotes: 2

Views: 683

Answers (2)

Reza Aghaei
Reza Aghaei

Reputation: 125217

You are running the whole code using Invoke. It means you are switching to UI thread and the code is running in UI thread. Since the code is a time-consuming for loop, then it's blocking UI thread.

Instead of using a BackgroundWorker, to format cells, it's better to use CellFormatting event:

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.
    }
}

Upvotes: 1

Faisal
Faisal

Reputation: 33

Maybe try to disable the Button when it get clicked until the job done?.

Lets say your Button name is Button1,

when the user click on the Enabled false data grid view, use Button.enabled=false, then when the job is done use Button.enabled=true

hope that helps!

Upvotes: 0

Related Questions