zt: http://www.x2blog.cn/jinhong618/?tid=22389
在設計中為了讓介面與邏輯分離,我的做法是使用事件,介面只要響應事件來處理介面的顯示就行了。而事件在邏輯處理中可能由不同的線程引發,這些事件的回應程式法在修改介面中的控制項內容時便會引發一個異常。
這時就用到了Control.InvokeRequired 屬性 與Invoke方法。
MSDN中說:
擷取一個值,該值指示調用方在對控制項進行方法調用時是否必須調用 Invoke 方法,因為調用方位於建立控制項所在的線程以外的線程中。
如果控制項的 Handle 是在與調用線程不同的線程上建立的(說明您必須通過 Invoke 方法對控制項進行調用),則為 true;否則為 false。
Windows 表單中的控制項被綁定到特定的線程,不具備執行緒安全性。因此,如果從另一個線程調用控制項的方法,那麼必須使用控制項的一個 Invoke 方法來將調用封送到適當的線程。該屬性可用於確定是否必須調用 Invoke 方法,當不知道什麼線程擁有控制項時這很有用。
下面來說下這個的用法(我的一般做法):
首先定義一個委託,與這個事件處理函數的簽名一樣委託,當然直接使用該事件的委託也是可以的,如:
private delegate void InvokeCallback(string msg);
然後就是判斷這個屬性的值來決定是否要調用Invoke函數:
void m_comm_MessageEvent(string msg)
{
if(txtMessage.InvokeRequired)
{
InvokeCallbackmsgCallback = new InvokeCallback(m_comm_MessageEvent);
txtMessage.Invoke(msgCallback, new object[] { msg });
}
else
{
txtMessage.Text = msg;
}
}
說明:這個函數就是事件處理函數,txtMessage是一個文字框。
這樣就做到了表單中控制項的執行緒安全性。