在一个非UI线程创建控件 [英] Creating controls in a non-UI thread

查看:177
本文介绍了在一个非UI线程创建控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

予具有其中各种复杂的用户控制被存储在DLL和加载和实例化在运行时使用一类的插件模型

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

由于我装了不少,这些我想这样做的背景下,保持我的UI响应,通过创建一个新的线程做加载。该控件然后父的主要形式,并在需要时显示。

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.

这似乎做工精细 - 直到我尝试在其中的一个用户控件,例如设置任何嵌套控制的任何财产在一个按钮,它抛出一个跨线程异常的事件处理程序。我不知道我可以检查InvokeRequired我每次访问一个属性时避免这种情况,但我宁愿没有写code用户控件(特别是因为有别人写$的这些位时,担心C $Ç过谁可能不会永远记住)。

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?

我希望我提供的信息足以使我的情况清楚;如果不是我会很高兴来阐述,并提供code样本。

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.

推荐答案

是罚款加载DLL和在后台创建的控制对象,但控制已被添加到主线程的形式和所有用户交互以及控制特性的任何程序改变(被创建后)都发生在主线程。我们根本没有办法解决这个,因为你可能已经知道。现在,除非这些DLL和控制创造的负载需要年龄,我看不出有任何理由这样做在单独的后台线程。

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.

如果通过控制执行某些操作的阻塞UI,并且希望他们能够出现在后台,这是一个不同的故事,你最好考虑在个人基础上的每个动作,创造明确的方法UI线程之间的通信和后台线程。

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.

试图做一个通用的一个一成不变的框架,以同样的UI线程模式和后台模式,简单地检查InvokeRequired结果有时的糟糕的性能(因为所有线程被阻塞在将Invoke),甚至在(未检测),一旦应用程序到达一个合理的复杂性锁死。同时做所有的更新异步的BeginInvoke的,W / O分别考虑每个方法,可能会导致数据一致性问题(即控制可以更新自己的状态的的时间,由于扭转线程之间的调用顺序)。

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

这篇关于在一个非UI线程创建控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆