0

I've got a question regarding multithreading in an application. I've got 2 forms - one mainForm and one editForm. The editForm is called by the mainForm on user request. The editForm has implemented a datagrid, which should be filled by a thread. I've done it this way:

    try
{
                InitializeComponent();
                Thread loadingDatagridThread = new Thread(new ThreadStart(() =>
                {
                                this.LoadDataGrid();
                }));
                loadingDatagridThread.Name = "LoadingDatagridThread";
                loadingDatagridThread.Start();
}
catch (Exception exp)
{
                throw exp;
}

The "LoadDataGrid" method looks like this:

private void LoadDataGrid()
{
                try
                {
                                this.picBox_Loading.Visible = true;
                                if (this.InvokeRequired == true)
                                {
                                                this.HaulierList = new Classes.HaulierCollection(Classes.HaulierCollectionKind.ByStopFlag, new object[] { 0 });
                                                this.BeginInvoke(new LoadDataGridDelegate(this.LoadDataGrid));
                                                return;
                                }
                                else
                                {
                                 //Fill the grid
                                }
                }
}

The collection of the datagrid (HaulierCollection) is being loaded while it is in the thread. The datagrid then is being filled when in the Main Thread, when InvokeRequired is false. This scenario works fine, if I work in Visual Studio and test it in Debug mode. I can close and re-open the editForm and the data of the datagrid is always being loaded. BUT if I start the EXE file of the solution from the debug folder without using Visual Studio Debug mode, the datagrid of the editForm is being filled only the first time I open it. The next times the datagrid is always empty. I found out, that this behaviour is caused by the InvokeRequired property. The first time I open the editForm it is InvokeRequired = true, but if I close the form and re-open it, it is always false. But why? I dispose the form, when the form is closed.

private void EditForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        this.Dispose();
    }

Why is InvokeRequired always false, when re-opening the editForm? Can anybody help please?

dns_nx
  • 3,651
  • 4
  • 37
  • 66
  • How Do You open the new form ? Do You use a using directive ? – icbytes Mar 31 '15 at 12:52
  • I just create a new instance of the form and then do showDialog(): private void haulierBasisDataToolStripMenuItem_Click(object sender, EventArgs e) { try { Forms.EditForm editForm = new Forms.EditForm(); editForm.ShowDialog(); } catch (Exception exp) { throw exp; } } – dns_nx Mar 31 '15 at 12:55
  • You create a new instance EACH time, You want to Show a form ? The variable of the form is globally declared ? – icbytes Mar 31 '15 at 12:56
  • Yes, I create a new instance each time. But this doesn't answer my question or does it? I thought, in the constructor of the form the thread is created and then the data is being loaded. Why not 2nd, 3rd... time. – dns_nx Mar 31 '15 at 12:58
  • It might be, that Your instance is never cleared out, making the following runs running in main thread, where is no invoke required Try to use a using directive to be more hard to the killing of the instance. Or You ran into: http://stackoverflow.com/questions/808867/invoke-or-begininvoke-cannot-be-called-on-a-control-until-the-window-handle-has-b – icbytes Mar 31 '15 at 13:01
  • Can you please give me an example how using directive? I'm not sure what you mean. Thanks in advance. – dns_nx Mar 31 '15 at 13:10
  • http://stackoverflow.com/questions/8315125/using-statement-around-dialog-form-to-ensure-garbage-collection – icbytes Mar 31 '15 at 13:21
  • Ok, thanks, but this does not work as well. Isn't it strange, that in debug mode in Visual Studio this behaviour does not appear? – dns_nx Mar 31 '15 at 13:23
  • 1
    This is standard, AFAIK, You will face such problems if dealing with multithreading. Check my link for further information about IsHandleCreated and so on. – icbytes Mar 31 '15 at 13:26
  • Unrelated, but change `throw exp;` to `throw;` – H H Mar 31 '15 at 21:18
  • Lots of relevant code is missing but the Dispose() is in the wrong place (use a using(){} in the menu_click). – H H Mar 31 '15 at 21:22
  • From the vague description, it sounds like you are seeing `InvokeRequired` being `false` when the thread manages to start executing before the UI thread can show the form and `true` otherwise; `InvokeRequired` isn't going to be `true` until the form's window handle has been created, which doesn't happen until the form's actually shown the first time. I.e. it's basically a timing issue with two threads racing each other. Without [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) it would not be possible to provide a precise diagnosis though. – Peter Duniho Apr 01 '15 at 03:19
  • Ok, thanks for your help. I thought, I gave all relevant information and needed code. Sorry, if something relevant is missing. It was the handleCreated issue. I put my thread start code into the form loaded (shown) event and then it worked. Thanks for help. – dns_nx Apr 01 '15 at 05:41

1 Answers1

-1

It was the handleCreated issue. I put my thread start code into the form loaded (shown) event of my editForm and then it worked. Thanks for help.

dns_nx
  • 3,651
  • 4
  • 37
  • 66