Control.InvokeRequired 属性

定义

获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。

public:
 property bool InvokeRequired { bool get(); };
[System.ComponentModel.Browsable(false)]
public bool InvokeRequired { get; }
[<System.ComponentModel.Browsable(false)>]
member this.InvokeRequired : bool
Public ReadOnly Property InvokeRequired As Boolean

属性值

如果控件的 true 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 Handle;否则为 false

实现

属性

注解

Windows 窗体 中的控件绑定到特定线程,并且不是线程安全的。 因此,如果要从其他线程调用控件的 方法,则必须使用控件的调用方法之一来封送对正确线程的调用。 此属性可用于确定是否必须调用调用方法,如果不知道哪个线程拥有控件,此方法可能很有用。

注意

除了 InvokeRequired 属性之外,控件上还有四个可调用线程安全的方法:InvokeBeginInvokeEndInvoke以及CreateGraphics控件的句柄是否已创建。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,在从其他线程调用时,应使用这些调用方法之一。

如果控件的句柄尚不存在, InvokeRequired 请向上搜索控件的父链,直到找到具有窗口句柄的控件或窗体。 如果找不到适当的句柄,该方法 InvokeRequiredfalse返回 。

这意味着InvokeRequired,如果 Invoke 不需要 , (调用发生在同一线程) ,或者控件是在不同的线程上创建的,但尚未创建控件的句柄,则可以返回 false

在尚未创建控件句柄的情况下,不应简单地对控件调用属性、方法或事件。 这可能会导致控件的句柄在后台线程上创建,从而在没有消息泵的线程上隔离控件,并使应用程序不稳定。

还可以检查 在后台线程上返回falseInvokeRequired 的值IsHandleCreated,防止出现这种情况。 如果尚未创建控件句柄,则必须等到创建它后再调用 InvokeBeginInvoke。 通常,仅当在应用程序的主窗体的构造函数中创建后台线程时,才会发生这种情况, (如 中所示 Application.Run(new MainForm()),然后才显示或 Application.Run 调用该窗体。

一种解决方案是等到创建窗体的句柄后再启动后台线程。 通过调用 Handle 属性强制创建句柄,或等待 Load 事件启动后台进程。

更好的解决方案是使用 SynchronizationContext 返回的 SynchronizationContext 而不是用于跨线程封送处理的控件。

注意

如果应处理消息的线程不再处于活动状态,可能会引发异常。

有关多线程Windows 窗体控件的详细信息,请参阅如何:使用后台线程搜索文件和如何:对Windows 窗体控件进行Thread-Safe调用

适用于

另请参阅