Control.InvokeRequired 属性
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 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 属性之外,控件上还有四个可调用线程安全的方法:Invoke、BeginInvokeEndInvoke以及CreateGraphics控件的句柄是否已创建。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,在从其他线程调用时,应使用这些调用方法之一。
如果控件的句柄尚不存在, InvokeRequired 请向上搜索控件的父链,直到找到具有窗口句柄的控件或窗体。 如果找不到适当的句柄,该方法 InvokeRequired 将 false
返回 。
这意味着InvokeRequired,如果 Invoke 不需要 , (调用发生在同一线程) ,或者控件是在不同的线程上创建的,但尚未创建控件的句柄,则可以返回 false
。
在尚未创建控件句柄的情况下,不应简单地对控件调用属性、方法或事件。 这可能会导致控件的句柄在后台线程上创建,从而在没有消息泵的线程上隔离控件,并使应用程序不稳定。
还可以检查 在后台线程上返回false
时 InvokeRequired 的值IsHandleCreated,防止出现这种情况。 如果尚未创建控件句柄,则必须等到创建它后再调用 Invoke 或 BeginInvoke。 通常,仅当在应用程序的主窗体的构造函数中创建后台线程时,才会发生这种情况, (如 中所示 Application.Run(new MainForm())
,然后才显示或 Application.Run
调用该窗体。
一种解决方案是等到创建窗体的句柄后再启动后台线程。 通过调用 Handle 属性强制创建句柄,或等待 Load 事件启动后台进程。
更好的解决方案是使用 SynchronizationContext
返回的 SynchronizationContext 而不是用于跨线程封送处理的控件。
注意
如果应处理消息的线程不再处于活动状态,可能会引发异常。
有关多线程Windows 窗体控件的详细信息,请参阅如何:使用后台线程搜索文件和如何:对Windows 窗体控件进行Thread-Safe调用。