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

本文关键字:线程 控件 单独 操作 无效 | 更新日期: 2023-09-27 18:16:54

这是我正在尝试做的一个简化的例子:

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

还是我真的不应该在主 GUI 线程之外创建 GUI 元素?

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

还是我真的不应该在主 GUI 线程之外创建 GUI 元素?

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

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

例如,如果要从某个外部源加载一组数据,则可以创建控件,并启动后台线程来加载数据。 加载数据后,可以更新控件以反映它。 这将导致它始终保持响应。

创建控件可能

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

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

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

它可能很"丑陋",但它会起作用并保持简单。

Forms.Timer,如果你问;)

是的,永远不要弄乱同一表单上的多个线程。 您可以在多个线程上拥有多个表单,但要做到这一点,您必须首先运行一个新线程,然后在其上创建一个表单。 它将有自己的消息循环,并且会做得很好。