訪問 windows 窗體控制項本質上不是執行緒安全的。如果有兩個或多個執行緒操作某一控制項的狀態,則可能會迫使該控制項進入一種不一致的狀態。還可能出現其他與執行緒相關的 bug,包括爭用情況和死鎖。所以,確保以執行緒安全方式訪問控制項是非常重要的。
private static object datalock = new object(); // 多執行緒訪問鍊錶使用的鎖
private listdatalist = new list();
bool is_test_thread_run;
private uint m_serialnumber = 0;
private void testthreadfunc()
// 每當鍊錶中有資料時就在listview中顯示該條資料
int count = 0;
while (0 < (count = datalist.count))
datalist.remove(param);}}
}}private void button_start_thread_click(object sender, eventargs e)
private void button_pushback_data_click(object sender, eventargs e)}}
}這裡的這個程式想要開啟乙個執行緒,在這個執行緒裡一直去讀取乙個鍊錶中的資料,只要鍊錶中有資料就把這個資料和當前的時間新增到上面的listview中。但是當訪問listview控制項顯示資料的時候就會出現異常中斷,提示你在不是建立控制項listview的執行緒裡訪問了它。
第一種方法是把checkforillegalcrossthreadcalls設定為false,禁止編譯器對跨執行緒訪問作檢查。這樣可以實現在另外的執行緒訪問控制項,但是這種方法並不安全,不能保證c#跨執行緒訪問控制項的執行時錯誤。
// 在初始化控制項後就可以把這個屬性設定為false,編譯器就不會對跨執行緒訪問做檢查
public form1()
methodinvoker 表示乙個委託,該委託可以執行託管**中宣告為void且不接受任何引數的任何方法。在對控制項的 invoke 方法進行呼叫時或需要乙個簡單委託又不想自己定義時可以使用該委託。我們可以這樣修改一下我們上面的**:
using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.windows.forms;
using system.threading;
namespace treadtest
private thread test_thread_run = null;
private static object datalock = new object(); // 多執行緒訪問鍊錶使用的鎖
private listdatalist = new list();
bool is_test_thread_run;
private static object displaydataobj = new object();
private uint m_serialnumber = 0;
private void testthreadfunc()
// 每當鍊錶中有資料時就在listview中顯示該條資料
int count = 0;
while (0 < (count = datalist.count))
datalist.remove(param);}}
}}private void showtranscomrecdata(string str)
catch
});}
}private void button_start_thread_click(object sender, eventargs e)
private void button_pushback_data_click(object sender, eventargs e)}}
}
每個控制項都有乙個invokerequired屬性,當乙個控制項的invokerequired屬性值為真時,說明有乙個建立它以外的執行緒想訪問它。此時它將會在內部呼叫new methodinvoker(loadglobalimage)來完成下面的步驟,實質上和上面一種方法是一樣的,這個做法保證了控制項的安全。你可以這樣理解,有人想找你借錢,他可以直接在你的錢包中拿,這樣太不安全,因此必須讓別人先要告訴你,你再從自己的錢包把錢拿出來借給別人,這樣就安全了。可以這樣修改最上面的**:
using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.windows.forms;
using system.threading;
namespace treadtest
private thread test_thread_run = null;
private static object datalock = new object(); // 多執行緒訪問鍊錶使用的鎖
private listdatalist = new list();
bool is_test_thread_run;
private static object displaydataobj = new object();
private uint m_serialnumber = 0;
private void testthreadfunc()
// 每當鍊錶中有資料時就在listview中顯示該條資料
int count = 0;
while (0 < (count = datalist.count))
datalist.remove(param);}}
}}delegate void settextcallback(string text);
private void showtranscomrecdata(string str));}
else
}private void button_start_thread_click(object sender, eventargs e)
private void button_pushback_data_click(object sender, eventargs e)}}
}
按照上面的三種方式修改後,可以看到程式能夠按照我們的想的那樣一直顯示鍊錶的資料了
跨執行緒訪問控制項
using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.linq using system.text u...
跨執行緒訪問控制項
程序是作業系統分配資源的最小單位,程序之間隔離,作為資源的擁有者,在建立 cpu處理時切換以及撤銷的過程中花費時間較長,而執行緒是作業系統任務排程的最小單元,對於每個程序中由多個列表內容執行緒執行對應的方法體,完成後立即釋放,這樣作業系統對執行緒處理起來更加容易,實現了併發程式。using syst...
初試C 多執行緒 跨執行緒訪問控制項
c 裡建立執行緒的方式是 thread t new thread new threadstart this.dosomething t.start 裡面的dosomething是主線程裡的乙個函式,在裡面做自己需要的操作。那我就建了乙個winform程式來試一下,畫了乙個button1,乙個text...