Control.InvokeRequired 属性

定义

获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 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.

这意味着,如果不需要 Invoke (调用发生在同一线程上),则 InvokeRequired 返回 false; 如果控件是在另一个线程上创建,但尚未创建控件的句柄,则返回。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.

InvokeRequired 在后台线程上返回 false 时,还可以通过检查 IsHandleCreated 的值来防范这种情况。You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. 如果尚未创建控件句柄,则必须等待,直到在调用 InvokeBeginInvoke 之前创建它。If 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 窗体控件的详细信息,请参阅 How:使用后台线程搜索文件操作方法:对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.

适用于

另请参阅