Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
490 views
in Technique[技术] by (71.8m points)

.net - Creating controls in a non-UI thread

I have a sort of plug-in model in which various complex user controls are stored in DLLs and loaded and instantiated at run time using

Activator.CreateInstanceFrom(dllpath, classname).

Since I'm loading quite a few of these I wanted to do it in the background, keeping my UI responsive, by creating a new thread to do the loading. The controls are then parented to the main form and displayed when needed.

This seems to work fine - until I try to set any property on any nested control on one of these user controls, e.g. in the event handler of a button, which throws a cross threading exception. I do realize I could avoid this by checking InvokeRequired every time I access a property, but I'd rather not have to worry about that when writing the code for the user controls (especially since there are others writing these bits of code too who might not always remember).

So my question is, is there any safe way to do what I'm attempting, or how should I best go about loading these controls in the background? Or is it basically impossible and do I have to stick to the main thread for creating controls?

I hope that the information I've provided is enough to make my situation clear; if not I'd be glad to elaborate and provide code samples.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Is fine to load the DLLs and create the control objects in the background, but the control has to be added to the form in the main thread and all user interaction as well as any programmatic change of control properties (after it was created) has to occur in the main thread. There is simply no way around this, as you probably already know. Now unless the load of those DLLs and control creation takes ages, I see no reason to do it in separate background threads.

If certain actions performed by the controls are blocking the UI and you want them to occur in the background, this is a different story, and you better consider each action on an individual basis and create explicit methods to communicate between UI thread and background threads.

Attempting to do a generic one-fits-all framework that works the same in UI thread mode and in background mode and simply checks the InvokeRequired results sometimes in worse performance (as all threads are blocked in the Invoke) or even in (undetected) deadlocks as soon as the application reaches a reasonable complexity. Also doing all updates async in BeginInvoke, w/o considering each method individually, can result in data consistency problems (ie. controls may update themselves to states back in time due to reversing of the invocation order between threads).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...