I\'m very new to threads, so my thoughts and questions might be a bit silly :)
I fill WinForm control with data from another thread, so I have to call <
This is absolutely wrong:
treeViewWriter.Start();
treeViewWriter.Join();
Never call Thread.Join from Main Thread! because that Join freezes the application and all those BeginInvoke/Invoke never gets fully executed because the message is not handled.
This is how BeginInvoke() actually works:
Application.DoEvents() (or the like which is always called in Application.Run())BeginInvoke()WaitHandle in IAsyncResult)EndInvoke() waits for such signal (or if IAsyncResult from BeginInvoke is never stored, it gets garbage-collected)So again: you eiter write it purely event-driven or do something like this:
private bool done = false;
void click(object, EventArgs) {
thread.Start();
while(!done) Application.DoEvents();
tree.ExpandAll();
}
ADDON:
Eihter use Invoke() (synchronized) and the above loop with Application.DoEvents()
or use BeginInvoke() and call your ExpandAll the same way (through BeginInvoke() from the thread)
ADDON2:
private bool done;
void click(object,EventArgs) {
done = false; // init state
new Thread(work).Start(); // start backgound work
while(!done) Application.DoEvents(); // wait until done
finish(); } // finish the job in main thread
void work() {
Thread.Sleep(100); // do your work
done = true; } // signal done
void finish() {
whatever(); } // called on main thread
void click2(object,EventArgs) {
new Thread(work2).Start(); } // just start the hread
void work2() {
Thread.Sleep(100); // do your work
BeginInvoke(new Action(finish)); } // execute finish() on main thread
Create an Action which Invokes the delegate, then BeginInvoke that action.
This way you will have a callback which you can move the ExpandAll into:
if (tree.InvokeRequired)
new Action(() => { tree.Invoke(code, tree); }).BeginInvoke((ar) => {
treeDirectoryContents.ExpandAll();
}, null);
else
code.Invoke(tree);
Note that I replaced your original BeginInvoke with a simple Invoke.
UPDATE: As firda mentioned correctly, because the main thread is blocked inside the Join method waiting for the other thread to exit, executing Invoke on the controls will lead to a deadlock. So now that your ExpandAll is moved to the callback, you should remove the Join and everything will be fine.