Creating forms on a non UI thread

G

Graham Allwood

Hi

Could someone clarify something for me please?

There is a rule about not creating a Windows control on a non UI thread
isn't there but what exactly is the rule. Is it I shouldn't construct a
control on a non UI thread or I shouldn't Show a control on a non UI thread.

If I have a callback method that is invoked when a worker thread completes.
The callback method needs to display a form with some information obtained
from the worker thread. Now, the callback method is actually executed on the
worker thread, not the UI thread and so I'm creating the UI control on a
different thread. I do however have a ShowControl() method on the main form
that I call to display the newly create control and this method checks the
Form.InvokeRequired property before calling Show(), calling Invoke() if
required.

Is this the correct way of doing it or should I also be asking the UI thread
(aka the main form) to create the new UI control as well?

Hope this all make sense!!

Regards

Graham Allwood
 
H

Herfried K. Wagner [MVP]

* "Graham Allwood said:
Could someone clarify something for me please?

There is a rule about not creating a Windows control on a non UI thread
isn't there but what exactly is the rule. Is it I shouldn't construct a
control on a non UI thread or I shouldn't Show a control on a non UI thread.

If I have a callback method that is invoked when a worker thread completes.
The callback method needs to display a form with some information obtained
from the worker thread. Now, the callback method is actually executed on the
worker thread, not the UI thread and so I'm creating the UI control on a
different thread. I do however have a ShowControl() method on the main form
that I call to display the newly create control and this method checks the
Form.InvokeRequired property before calling Show(), calling Invoke() if
required.

Is this the correct way of doing it or should I also be asking the UI thread
(aka the main form) to create the new UI control as well?

Keep creation of controls in the main thread too.
 
1

100

Hi Graham,

This is verry interesting question or at least for me ;)
The question is *what has to be created insite the UI thread?*. The UI
thread has to create the underlaying windows control. So, this is Windows OS
issue not .NET. And hopwefully it won't be like that when Longhorn comes.
Because of that you can create whatever .NET object you want in whatever
worker thread you want and pass the object to another thread. However
because of Windows your application will crash if you try to add a windows
control created in one thread to windows control created in another thread.
So the qestion is when the underalayng windows control is created in your
scenario. Creating .NET object with new doesn't create the windows control.
The last point where you will have the windows control created is the
control's Show method. As matter of fact the framework throws exception if
you try to add control created in one thread as a child to control created
in another. I believe all windwos form's controls create their windows
handler (HWND) in *Show* method and in this case you are safe with them.
However, you might have problems with some third-party controls.

To test whether a control created from another thread and sent to the UI
thread can be added safely to the control collection you can check
Control.IsHandleCreated and if it is *false* you can add the control; if it
is *true* you have to recreate control's handle in the UI thread. Control
objects has method RecreateHandle method, which is protected, though. I
tried to use that methods and it works.

HTH
B\rgds
100
 
G

Graham Allwood

Hmm, a tough one. On the one hand I could risk constructing the controls in
the worker thread and then displaying then from the UI thread or I could
play safe and get the UI thread to create the control as well. Taking the
safer approach does anyone have any comments on the easiest way for my UI
thread to create a generic control for my worker thread? At present I have a
method on the main form class that takes a Type and object[] for the
parameters. I then get the constructor info for the ctor with the correct
signature and then invoke that. The resultant object I pass back to the
worker thread. The reason I need this generic method is because my worker
threads can create many different user control types depending on what they
have been asked to do.

Thanks for your help

Graham
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top