【问题标题】:C# cross-thread operation not valid, 2 controls and 2 separate threadsC#跨线程操作无效,2个控件和2个独立线程
【发布时间】:2011-12-06 23:00:19
【问题描述】:

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

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

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

【问题讨论】:

  • 或者我真的不应该在主 GUI 线程之外创建 GUI 元素? - 通常。您真的需要在另一个线程中创建控件吗?为什么仅仅创建它就如此昂贵?难道你不能廉价地创建控件并使用后台线程来加载数据或做任何你需要做的事情吗?
  • 如果可能的话,在不同的线程上创建控件会让人头疼。在 UI 线程上创建它们。使用 p.Invoke() 调用创建 c 的方法。
  • 不幸的是,这是一个封闭源代码的第 3 方控件。我想我去看看,看看能不能把慢的部分分离出来。

标签: c# .net multithreading invoke


【解决方案1】:

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

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

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

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

【讨论】:

  • 不幸的是,这是一个封闭源代码的第 3 方控件。我想我去看看,看看能不能把慢的部分分离出来。
  • @fred 通常,这是在创建后而不是在设计时设置属性(即:绑定的数据等)的问题。
【解决方案2】:

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

【讨论】:

  • 不幸的是,这是一个封闭源代码的第 3 方控件。我想我去看看,看看能不能把慢的部分分离出来。
【解决方案3】:

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

Timer 创建c,它将定期触发并且在设置_backgroundCompleted 之前什么都不做,然后创建c,然后终止计时器。

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

Forms.Timer,如果你问的话;)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2011-07-11
    相关资源
    最近更新 更多