Creating controls in a non-UI thread

前端 未结 3 943
悲哀的现实
悲哀的现实 2020-12-18 03:54

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.CreateInsta         


        
相关标签:
3条回答
  • 2020-12-18 04:23

    The code sample in this answer provides an elegant way around this problem.

    Code quoted from that answer:

    public void UpdateTestBox(string newText)
    {
        BeginInvoke((MethodInvoker) delegate {
            tb_output.Text = newText;
        });        
    }
    

    ...although in your case you would want to call BeginInvoke on the controls themselves:

    public void UpdateTestBox(string newText)
    {
        tb_output.BeginInvoke((MethodInvoker) delegate {
            tb_output.Text = newText;
        });        
    }
    
    0 讨论(0)
  • 2020-12-18 04:24

    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).

    0 讨论(0)
  • 2020-12-18 04:42

    Not knowing the details of the InvokeRequired mechanism, I have been experimenting a little and afaik you can set most properties in a Thread as long as it has not been Parented (ie added to some Control.Controls property).

    So you should be able to prepare your controls, store them in a list and attach them to the main UI in an Invoked method.


    Edit: I don't think it matters which Thread created a Control. So the normal rules should apply, ie you can only work with controls form the main Windows thread. And I think the criterion is HandleCreated rather than Parented. As long as that hasn't happened you get a little respite.

    0 讨论(0)
提交回复
热议问题