简体   繁体   中英

C# cross-thread operation not valid, 2 controls and 2 separate threads

Here's a simplified example of what I'm trying to do:

I have 2 controls MyControl c and Panel p . p is created in the main GUI thread as normal, but I want c to be created in a background thread, because it takes awhile and I don't want to freeze the GUI. How can I add c to p.Controls ? If I do it in this.Invoke it throws an exception for c , and if I do it from the background thread it throws an exception for p .

Or is it that I really shouldn't be creating GUI elements outside of the main GUI thread?

Or is it that I really shouldn't be creating GUI elements outside of the main GUI thread?

Yes, this is basically the problem. Most controls have thread affinity, and must be created within the user interface thread.

Typically, the way to handle this is to move the "work" that is causing the control creation to be slow onto a background thread, but still create the control on the UI thread. You'd then use Control.Invoke or Control.BeginInvoke to update the information in the UI once the slow work was completed.

For example, if you're loading a set of data from some external source, you can create the control, and start a background thread to load the data. Once the data is loaded, you can then update the control to reflect it. This will cause it to stay responsive the entire time.

It may be that your control does not take a long time to create; rather it takes a long time to get its data. In that case, consider creating a control that can display it UI while it is being populated. Then you can create the control in your main thread, populate it in a background thread, and give your users a better experience.

Use background thread to do what it has to do, and then signal somehow ( bool _backgroundCompleted as a trivial example) that c is ready to be created.

Create c from Timer that will fire periodically and do nothing until _backgroundCompleted is set, then create c , then kill the timer.

It might be 'ugly', but it will work and will remain simple.

Forms.Timer , if you are asking ;)

And yeah, NEVER ever mess with multiple threads on the same form. You can have several forms on several threads, but to do that, you have to first RUN a new thread, then create a form ON it. It will have its own message loop, and will do fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM