Hi, I came to this exception: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. and I don't know what to do with it.
My application creates some Panels with a lot of components at run time (according to the database entries). Each panel takes a second or two to load so I decied to use multithreading and choosed the ThreadPool.
Simply something like that:
(for each page in Form_Shown)
Thread.QueueUserWorkItem( <delegate to CreateFormPage> )
...
private Panel CreateFormPage(byte page)
{
Panel r = new Panel();
ComboBox cbx = new ComboBox(); // for example, in fact using reflection on control type stored in table
cbx.AutoCompleteMode = AutoCompleteMode.Suggest; // ThreadStateException
...
r.Controls.Add(cbx);
return r;
}
I know that I cannot modify the form from another thread than the GUI one, but I'm creating the controls on the separate thread and modifying them from the same thread (planning to add the final panel to the form in the GUI thread)... this is also illegal How should I do it then

ThreadStateException from background thread manipulating its control
Jcastro
Does this mean I cannot prepare the controls on the background thread Does this mean I am not able to use multithreading at all
Why is the exception never thrown during the control's creation
Ayo Soul
Well I did a win32 stuff a long time ago and know that combobox styles are being set using messages and style values, but I thought it's handle to do that can be used without the form's handle.
If not possible, well not possible. So, I would than ask: As far as knowing win32 stuff I absolutely don't know about Invoke/BeginInvoke - does this interrupt the main thread from doing the other GUI things (like repainting). If so, is there any way to 1] prepare the panels simultaneously or 2] run the Layout stuff on different thread (no control properties other than this 'bounds' stuff are being changed)
Second solution, that cames to my mind... to override the WndProc and manually dispatch the messages I need to
RussellF
Takrim Khan
Because there are about 50 controls on the page, and by control I mean for example heading+control image+option buttons group+validaton image. These perform autosize, are wrappable and aligned like free flowlayout... like a web page :).
Only part of the application deals with these pages. And even in this part, sooner than you realize and choose by which data you want to fill all these controls, they are already loaded.
Ok the initial layout takes such long time, the resize is not so expensive, say second or two. (maybe there should be no difference, though)
In fact, I have found that this operation takes so much time only on my development machine, I have tried it on another (much slower) and the complete startup with initial layouts is done in two seconds, which is acceptable.
So the calculation itself is not as bad as it looks like, in fact I have optimized it as much as I could, using DrawString instead of Labels, DrawImage instead of picture boxes, setting positions manually instead of tons of TablePanels with Docks set to Fill, adding all pages to the parent and changing only the Visible property instead of clearing the control collection and adding the right one. I don't believe much can be done more.
I am asking firstly because I was surprised I cannot modify the controls from the thread which (without problems) created them and because I would like to let the user work with the app while preparing some other parts - only by chance they are not dependent on the user's action in my example.
Frank Corrao
Invoke sends a message to the message pump for the control on which you are calling invoke. That message is processed like any other windows message, in the order in which it was inserted into the message queue; its not so much that it "interrupts" the main UI thread, as it uses that thread to do its work. But yes, the UI thread would be prevented from doing other things (like repainting) until the invoked message was finished. Begin/EndInvoke do the exact same thing asynchronously, i.e. BeginInvoke returns immediately, without waiting for the message to finish processing.
Overriding WndProc wont help you any, because WndProc only gets called from the UI therad anyway.
Why can you not simply create your controls on the UI thread If you do it in the load event of the form, everything will happen before the form is actually displayed, so the user wont see the controls appearing or anything. If the wait is too long, use some kind of splash page or "Please wait"/"Initializing" dialog to indicate that significant preparation work is occurring.
Devidas Joshi
P-ter
Ok, I thought about overriding the WndProc to achieve the behaviour of Invoke you described, so there is no point in it.
I can create them on the GUI thread, but all this layout computations takes a time. We're talking about tens of seconds. The thing is, that user can work with other parts of the application while loading these pages.
Every resize of the form starts the layouting again. I would like to do this in the background, rather than let the user wait some seconds on every page open. (Well at first I was creating and layouting only "on demand" but it was horrible to click a tree node and look some time to "frozen" window, so I moved the initial computations to the application startup).
Thank you for your help.
andrew M
Xavier Navarro
Unfortunately, most of the work is Layouting, in front of which is the reflection creation zero-time operation. (In fact I am creating about 500 controls splitted into 13 pages/panels, at the moment)
Adding the pages to the parent form is the last operation needed, with which I count to be held by the UI thread.
There is no reason for UI thread to try to manipulate with my controls as it doesn't know about them, does it
As long as the message pump is mentioned, I don't know about any message needed to be sent to my controls through the form - just because they aren't on the form!
Jendk