【问题标题】:Why i should call Control.Invoke from non-ui thread?为什么我应该从非 ui 线程调用 Control.Invoke?
【发布时间】:2010-07-21 14:54:08
【问题描述】:

为什么我应该从非 ui 线程调用 Control.Invoke?据我所知,任何带有控制的操作都是要控制的消息。所以当我打电话时,例如TextBox.Text =“text”,它会产生消息SendMessage(TextBox.Hanlde ...)。该消息将排入 UI 线程消息队列并由 UI 线程调度。为什么我必须调用invoke,即使它会产生相同的消息?

【问题讨论】:

    标签: winforms winapi


    【解决方案1】:

    MS 开发人员做出此限制的原因有两个:

    1. 某些 UI 函数可以访问线程本地存储 (TLS)。从另一个线程调用这些函数会导致 TLS 操作的结果不正确。

    2. 从同一个线程调用所有与 UI 相关的函数会自动将它们序列化,这是线程安全的,不需要同步。

    在我们看来,我们只需要遵循这些规则。

    【讨论】:

    • 好的,STA activex 组件怎么样,也许某些控件是 COM+ 对象?
    • 对不起,我没明白你的意思。我们谈论的是 Windows 窗体控件。也许他们中的一些人在内部使用 COM,但这不是他们公共接口的一部分。
    • 我的意思是,这个限制也保证了从 STA 线程执行 UI COM 对象。
    • 也许吧。我没有考虑 COM STA,这是另一个优势(对于 Windows 窗体开发人员,而不是用户)。
    【解决方案2】:

    因为您不能从创建它们的线程以外的线程直接访问 UI 控件。 Control.Invoke 会将您的调用编组到正确的线程 - 允许您从另一个线程调用 UI 线程,而无需了解自己的 UI 线程是什么或如何执行编组。

    更新:回答你的问题,你没有使用Control.Invoke - 如果你有代码将你的调用编组到正确的线程并发布向消息泵发送消息 - 然后使用它。然而,这被称为重新发明轮子。除非你正在做一些改变行为的事情。

    【讨论】:

    • 我知道 Control.Invoke 是如何工作的,我问为什么我不能直接调用。无论如何 TextBox.Text 会将消息放入 UI 线程消息队列
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多