Control.InvokeRequired Control.InvokeRequired Control.InvokeRequired Control.InvokeRequired Property

定义

获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.

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

属性值

如果控件的 true 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 Handle;否则为 falsetrue if the control's Handle was created on a different thread than the calling thread (indicating that you must make calls to the control through an invoke method); otherwise, false.

实现

注解

在 Windows 窗体控件绑定到特定线程并不是线程安全。Controls in Windows Forms are bound to a specific thread and are not thread safe. 因此,如果你正在从另一个线程调用控件的方法,您必须使用其中一个控件的调用封送到正确的线程调用的方法。Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread. 此属性可以用于确定是否必须调用 invoke 方法,如果您不知道在哪个线程拥有一个控件可能很有用。This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control.

备注

除了InvokeRequired属性,在控件上都是线程安全地调用的四种方法: InvokeBeginInvokeEndInvokeCreateGraphics如果已创建控件的句柄。In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke,BeginInvoke, EndInvoke and CreateGraphics if the handle for the control has already been created. 调用CreateGraphics后台线程上创建控件的句柄之前可能会导致非法的跨线程调用。Calling CreateGraphics before the control's handle has been created on a background thread can cause illegal cross thread calls. 对于所有其他方法调用,应使用其中一种从另一个线程调用时调用的方法。For all other method calls, you should use one of these invoke methods when calling from a different thread.

如果控件的句柄尚不存在,InvokeRequired搜索控件的父沿着链向上,直到它找到的控件或窗体具有一个窗口句柄。If the control's handle does not yet exist, InvokeRequired searches up the control's parent chain until it finds a control or form that does have a window handle. 如果找不到任何合适的句柄,InvokeRequired方法将返回falseIf no appropriate handle can be found, the InvokeRequired method returns false.

这意味着InvokeRequired可以返回false如果Invoke不是必需的 (调用发生在同一线程上),或如果在不同线程上创建该控件,但尚未创建控件的句柄。This means that InvokeRequired can return false if Invoke is not required (the call occurs on the same thread), or if the control was created on a different thread but the control's handle has not yet been created.

在控件的句柄尚未创建的情况下,不应只需调用属性、 方法或事件在控件上。In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. 这可能会导致在隔离没有消息泵线程上的控件并使应用程序不稳定的后台线程上创建控件的句柄。This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

你可以抵御这种情况下通过还检查的值IsHandleCreatedInvokeRequired返回false后台线程上。You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. 如果尚未创建控件句柄,必须等待,直到已创建,然后再调InvokeBeginInvokeIf the control handle has not yet been created, you must wait until it has been created before calling Invoke or BeginInvoke. 通常情况下,会发生此情况仅在应用程序的主窗体的构造函数中创建后台线程 (如Application.Run(new MainForm()),然后显示窗体或Application.Run已调用。Typically, this happens only if a background thread is created in the constructor of the primary form for the application (as in Application.Run(new MainForm()), before the form has been shown or Application.Run has been called.

一种解决方案是等待,直到启动后台线程之前已创建窗体的句柄。One solution is to wait until the form's handle has been created before starting the background thread. 可以通过调用强制创建句柄Handle属性,或者等待Load事件启动后台进程。Either force handle creation by calling the Handle property, or wait until the Load event to start the background process.

更好的解决方案是使用SynchronizationContext返回的SynchronizationContext而不是用于跨线程封送处理的控件。An even better solution is to use the SynchronizationContext returned by SynchronizationContext rather than a control for cross-thread marshaling.

备注

如果应处理该消息的线程不再处于活动状态,可能会引发异常。An exception might be thrown if the thread that should process the message is no longer active.

有关多线程 Windows 窗体控件的详细信息,请参阅如何:使用后台线程搜索文件如何:对 Windows 窗体控件进行线程安全调用For more information about multithreaded Windows Forms controls, see How to: Use a Background Thread to Search for Files and How to: Make Thread-Safe Calls to Windows Forms Controls.

适用于

另请参阅