[英]C# cross-thread operation not valid, 2 controls and 2 separate threads
这是我要执行的操作的简化示例:
我有2个控件MyControl c
和Panel p
。 p
是在GUI主线程中正常创建的,但是我希望c
在后台线程中创建,因为这需要一段时间,而且我不想冻结GUI。 如何将c
添加到p.Controls
? 如果我在this.Invoke
执行此操作,它将引发c
的异常,如果我从后台线程执行,则将引发p
的异常。
还是我真的不应该在主GUI线程之外创建GUI元素?
还是我真的不应该在主GUI线程之外创建GUI元素?
是的,这基本上是问题所在。 大多数控件具有线程关联性,并且必须在用户界面线程中创建。
通常,处理此问题的方法是将导致控件创建缓慢的“工作”移到后台线程上,但仍在UI线程上创建控件。 一旦缓慢的工作完成,您就可以使用Control.Invoke或Control.BeginInvoke来更新UI中的信息。
例如,如果要从某个外部源加载一组数据,则可以创建控件并启动后台线程以加载数据。 一旦数据被加载,你就可以更新控制,以反映它。 这将导致它始终保持响应状态。
可能是您的控件创建时间并不长。 而是需要很长时间才能获取其数据。 在这种情况下,请考虑创建一个可以在填充UI时显示其UI的控件。 然后,您可以在主线程中创建控件,将其填充到后台线程中,并为用户提供更好的体验。
使用后台线程执行它必须做的事情,然后以某种方式发出信号( bool _backgroundCompleted
作为一个简单的示例),表明已准备好创建c
。
从Timer
创建c
,它将定期启动,并且在设置_backgroundCompleted
之前不执行任何_backgroundCompleted
,然后创建c
,然后_backgroundCompleted
计时器。
它可能是“丑陋的”,但是它将起作用并且将保持简单。
Forms.Timer
,如果您要求;)
是的,永远不要搞乱相同形式的多个线程。 您可以在多个线程上拥有多个表单,但是要这样做,您必须首先运行一个新线程,然后在其上创建一个表单。 它将有自己的消息循环,并且会很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.