Windows 窗体控件仅可在创建它们的线程上执行,即它们不是线程安全的。如果要从后台线程获取或设置控件的属性或对控件调用方法,则必须将调用封送到创建该控件的线程。
在控件上有五个函数对于从任何线程调用都是安全的:InvokeRequired、Invoke、BeginInvoke、 EndInvoke 和 CreateGraphics。对于所有其他方法调用,应使用上述调用方法之一。
默认情况下,Windows 为您封送调用。但是,如果对某控件进行多次调用,则您自己创建一个执行这些调用的方法并且进行跨线程调用将有效得多。通过调用 Control.Invoke 方法之一进行跨线程调用。Invoke 方法采用对委托的引用。通常,此委托是 MethodInvoker 委托的一个实例。
public bool InvokeRequired { get ; }
如果调用方对此控件进行方法调用时必须调用 Invoke,则返回真。
public IAsyncResult BeginInvoke(Delegate method)public IAsyncResult BeginInvoke(Delegate method, Object[] args)
在拥有此控件的基础窗口句柄的线程上执行给定的委托。异步调用该委托并且该方法立即返回。可从任何线程调用此方法,甚至可以从拥有该控件的句柄的线程上调用。如果该控件的句柄尚不存在,将沿该控件的父链向上查找,直到找到确实有窗口句柄的控件或窗体。如果无法找到相应的句柄,BeginInvoke 将引发异常。此委托方法中的异常被视为未捕获的异常,将发送给应用程序的未捕获的异常处理程序。
public Object EndInvoke(IAsyncResult asyncResult)
public Object Invoke(Delegate method)public Object Invoke(Delegate method, Object[] args)
在拥有此控件的基础窗口句柄的线程上执行给定的委托。同步调用该委托并且此方法在调用的方法返回后立即返回。返回值是调用的方法的结果。在控件所属的同一个线程上调用此方法是错误的。
下面的示例演示如何创建一个后台线程,该线程使用 MethodInvoker 以固定时间间隔更新 ProgressBar 控件:
Powered by: C++博客 Copyright © 醒目西西