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 © 醒目西西