C#跨线程操作无效,2个控件和2个单独的线程

时间:2011-12-06 23:00:20

标签: c# .net multithreading invoke

以下是我正在尝试做的简化示例:

我有2个控件MyControl cPanel pp在主GUI线程中正常创建,但我希望在后台线程中创建c,因为它需要一段时间,我不想冻结GUI。如何将c添加到p.Controls?如果我在this.Invoke中执行此操作,则会为c抛出异常,如果我从后台线程执行此操作,则会为p抛出异常。

或者我真的不应该在主GUI线程之外创建GUI元素吗?

3 个答案:

答案 0 :(得分:3)

  

或者我真的不应该在主GUI线程之外创建GUI元素吗?

是的,这基本上就是问题所在。大多数控件都具有线程关联性,必须在用户界面线程中创建。

通常,处理此问题的方法是将导致控件创建的“工作”移动到后台线程上,但仍然在UI线程上创建控件。然后,在慢速工作完成后,您可以使用Control.Invoke或Control.BeginInvoke更新UI中的信息。

例如,如果您从某个外部源加载一组数据,则可以创建该控件,并启动后台线程来加载数据。加载数据后,您可以然后更新控件以反映它。这将使它在整个时间内保持响应。

答案 1 :(得分:1)

可能是您的控件不需要很长时间来创建;相反,它需要很长时间才能获得数据。在这种情况下,请考虑创建一个可以在填充时显示UI的控件。然后,您可以在主线程中创建控件,在后台线程中填充它,并为您的用户提供更好的体验。

答案 2 :(得分:1)

使用后台线程执行它必须执行的操作,然后以某种方式发出信号(bool _backgroundCompleted作为一个简单的示例)c已准备好创建。

c创建Timer,它会定期触发并在设置_backgroundCompleted之前不执行任何操作,然后创建c,然后终止计时器。

它可能是“丑陋的”,但它会起作用并且仍然很简单。

Forms.Timer,如果你问;)

是的,永远不要在同一个表单上混淆多个线程。您可以在多个线程上拥有多个表单,但要执行此操作,您必须首先运行新线程,然后在其上创建表单。它将有自己的消息循环,并且会很好。