BrightSoul
Feb 8th, 2005, 12:46 PM
Hello,
got some strange/serious stuff going on with a treeview.
As soon as I launch my application, I execute some asynchronous code. Depending on if it's the client or server version of my application, an event will fire with a very short or medium delay. That event notifies me that some data is available and that I can put it into a treeview as nodes.
If I launch my app as the server version I have no problem at all. The data is immediately available and the treeview is filled pretty nicely.
I have a problem with the client version. It runs the same code (is in fact the same executable) and the only difference is that the data is available with a longer delay (a few more milliseconds).
When I try to add the first node, the next lines of code DO NOT execute!! How could that be?
MessageBox.Show("Inserting " + myvar);
TreeView1.Nodes.Add(myvar);
MessageBox.Show("Inserted " + myvar);
On the client version I can't see the second messagebox, the code execution just *stops* at Treeview1.Nodes.Add(myvar);
I tried to mess up with ResumeLayout, BeginUpdate, Refresh but no use. I'm not sure why the .Add method won't accomplish its task. I don't get exceptions or anything.
After a few seconds that the client version has started I tried to reinvoke the method that fills the treeview by clicking a button and it worked!!
I'm wasting big hours on this :( doh
EDIT: oh wait, wait!!! I DO get an exception:
System.InvalidOperationException - The action being performed on this control is being called from the wrong thread. You must marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.
What the heck does that mean?!?
EDIT2: just found the solution, thanks anyways :) talking about problems makes them easier to solve :))
the problem with Windows' visual components is that you cannot modify visual
components from thread other that the one which created these components. it
does not work in Win32API and it does not work in .NET (however you get nice
exception message).
the problem should be resolved quite easily. you have to check whether you
are in the right thread and if not you should use .BeginInvoke or .Invoke.
here's how it works:
public delegate void VoidDelegate();
// form code, so this means 'current form'
if ( this.InvokeRequired == false )
{
// if we are in the thread that has created the form then we can
just call the method
MyMethod();
}
else
this.BeginInvoke( new VoidDelegate( MyMethod ) );
there are two things to remember:
1. if you need to call methods with different prototype, you should always
use correct delegate
(otherwise it will not even compile)
2. BeginInvoke invokes the method with the asynchronous call. if you do not
need it you can just use Invoke instead of BeginInvoke (it is more difficult
to collect the results if you use BeginInvoke but it does not stop the whole
program to wait for the method to complete).
--- COURTSY: Wiktor Zychla
got some strange/serious stuff going on with a treeview.
As soon as I launch my application, I execute some asynchronous code. Depending on if it's the client or server version of my application, an event will fire with a very short or medium delay. That event notifies me that some data is available and that I can put it into a treeview as nodes.
If I launch my app as the server version I have no problem at all. The data is immediately available and the treeview is filled pretty nicely.
I have a problem with the client version. It runs the same code (is in fact the same executable) and the only difference is that the data is available with a longer delay (a few more milliseconds).
When I try to add the first node, the next lines of code DO NOT execute!! How could that be?
MessageBox.Show("Inserting " + myvar);
TreeView1.Nodes.Add(myvar);
MessageBox.Show("Inserted " + myvar);
On the client version I can't see the second messagebox, the code execution just *stops* at Treeview1.Nodes.Add(myvar);
I tried to mess up with ResumeLayout, BeginUpdate, Refresh but no use. I'm not sure why the .Add method won't accomplish its task. I don't get exceptions or anything.
After a few seconds that the client version has started I tried to reinvoke the method that fills the treeview by clicking a button and it worked!!
I'm wasting big hours on this :( doh
EDIT: oh wait, wait!!! I DO get an exception:
System.InvalidOperationException - The action being performed on this control is being called from the wrong thread. You must marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.
What the heck does that mean?!?
EDIT2: just found the solution, thanks anyways :) talking about problems makes them easier to solve :))
the problem with Windows' visual components is that you cannot modify visual
components from thread other that the one which created these components. it
does not work in Win32API and it does not work in .NET (however you get nice
exception message).
the problem should be resolved quite easily. you have to check whether you
are in the right thread and if not you should use .BeginInvoke or .Invoke.
here's how it works:
public delegate void VoidDelegate();
// form code, so this means 'current form'
if ( this.InvokeRequired == false )
{
// if we are in the thread that has created the form then we can
just call the method
MyMethod();
}
else
this.BeginInvoke( new VoidDelegate( MyMethod ) );
there are two things to remember:
1. if you need to call methods with different prototype, you should always
use correct delegate
(otherwise it will not even compile)
2. BeginInvoke invokes the method with the asynchronous call. if you do not
need it you can just use Invoke instead of BeginInvoke (it is more difficult
to collect the results if you use BeginInvoke but it does not stop the whole
program to wait for the method to complete).
--- COURTSY: Wiktor Zychla