0

I've this situation:

Form "Menu" where you can click "New" and an insert form (with showdialog) will appear. If you insert data, I make an INSERT query on the database and I close this form. After showDialog() statement, I have a lot of methods who performs a lot of operations in a sequential way (MUCH IMPORTANT) and sometimes update a dataGridView. After all this computation, I simulate press of "new button" in order to allow user to insert a new item. This is an example:

private void buttonNew_Click(object sender, EventArgs e)
{
        DialogResult dr = new DialogResult();
        InsertForm form = new InsertForm();
        dr = form.ShowDialog();

        if (dr == System.Windows.Forms.DialogResult.OK)
        {
            Method1();
            Method2();
            if (dataGrid2.RowCount > 0)
            {
               Method3();
               Method4();
               Method5();
               Method6();
               Method7();
               Method8();  
            }
            bNew.PerformClick();
        }
}

The problem is that the "New" form (bNew.PerfomClick()) appear after a 2-3 seconds and I can't wait so much time. So I tried to create a method who include Method1 to Method8, run it in a new Thread and execut bNew.PerfomClick(), but this doesn't works because a lot of my methods update a datagridView.

Is there a way to solve this problems? Sorry for my bad english.

------------UPDATE------------------

Now I'm trying this code:

    delegate string OperazioniDelegate();

    private string Operazioni()
    {
        if (!InvokeRequired)
        {
            Method1();
            Method2();
            ............
        }
        else
             Invoke(new OperazioniDelegate(Operazioni));
        return "";
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Operazioni();
    }

In this way, new insert form is showed instantly but his UI is blocked until the backgroundWorker End work..

helloimyourmind
  • 994
  • 4
  • 14
  • 30
  • Possible duplicate: http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c?rq=1 – Onots Jan 07 '15 at 02:01
  • Hi, the problem is that I don't only need to update UI, I also need to execut a lot of operation in another thread and NEXT update ui.. – helloimyourmind Jan 07 '15 at 02:09

1 Answers1

0

Assuming you are running your long running operation in a seperate thread, which updates the UI elements (datagridview in your case), it is bound to experience cross thread exception, because the context in which background thread runs is different from that of UI thread. Either use InvokeRequired as given below:

delegate void valueDelegate(string value);

    private void SetValue(string value)
    {   
        if (someControl.InvokeRequired)
        {
            someControl.Invoke(new valueDelegate(SetValue),value);
        }
        else
        {
            someControl.Text = value;
        }
    }

or use BackGroundWorker class, which will do automatic marshalling of calls from background thread to Ui thread. Use of Background worker is given in this link http://www.albahari.com/threading/part3.aspx#_BackgroundWorker

Giri
  • 126
  • 1
  • 6
  • So I need to execute methods in separate threads each of one call "valueDelegate" when they need to update UI? – helloimyourmind Jan 07 '15 at 02:14
  • Yes you need to run your long running operation in a separate thread. But each one need not call the invoke required. This code should be there along with the UI code, say in the Form class. I would prefer using BackGroundWorker, as it will do this marshaling automatically and you will also have control on the operation like getting progress of the operation, or cancelling the operation – Giri Jan 07 '15 at 02:35
  • It looks like you are using both Invoke required and BackgroundWorker class. You should use either of them. BackgroundWorker class gives you methods to start the operation in background and when things change in the operation, you can directly update the UI (should not use InvokeRequired). This link gives examples of using BackgroundWorker:http://stackoverflow.com/questions/16521680/right-way-of-using-backgroundworker – Giri Jan 08 '15 at 01:22