開始正題前,大概敘述下委託,委託在.net 中就是類的特殊形式,用class 能夠定義各類類型,delegate 能夠定義各類類型的委託。定義好的委託至關於C語言中定義的函數類型,兩種定義和使用方式以下:安全
C:typedef void FunSample(int pValue); 符合的函數實例:void setValue(int pValue);多線程
FunSample *pf=setValue; 函數名爲函數在代碼段中的起始地址,此處定義指針變量標識該地址架構
C#:delegate void FunSample(int pValue);符合的函數實例:void setValue(int pValue);異步
FunSample fs=new FunSample(setValue);固然還有其餘的初始化方式,委託是一種類,因此能夠用關鍵字new進行實例化函數
再簡單說下Windows的GUI架構,目前Windows GUI的處理都是在一個單獨的GUI線程中的,每一個窗口有一個消息隊列,消息循環和處理消息的窗口過程。更詳細的內容可自行查看相關介紹。要構建一個響應友好,操做複雜的界面程序,不可避免的會使用到多線程。好比一個文件讀取操做,操做在GUI線程中執行,文件很大時,IO讀取勢必會很耗時,此時整個GUI線程將卡在文件讀取部分,其餘的消息,如移動,點擊等將不會獲得及時的處理,界面會卡住。所以,一些耗時操縱須要分離到另外的工做線程中。this
多線程的一個問題是對共享資源的競爭,GUI中會建立不少控件,GUI線程自己去操做這些控件不會有問題,可是其餘的線程同時操做這些控件而不去控制,就會出現競爭和不可預料的結果。因此,.net 中對非GUI線程操做GUI控件是作了限制的,同時也提供了幾種方式來容許外部線程對GUI控件的安全操做。本篇只介紹其中的一種方式:即經過控件的Invoke 和BeginInvoke 兩個函數將非GUI線程對控件的操做交給GUI線程去處理。spa
.net WinForm程序中的控件都實現了ISynchronizeInvoke接口,其中主要就是Invoke和BeginInvoke兩個方法。Invoke爲同步阻塞,BeginInvoke 爲異步非阻塞。.net
Invoke 的解釋爲在建立當前控件的基礎線程上同步執行給定的委託,BeginInvoke相同,只是要異步執行給定的委託。簡單來講,就是將要執行的操做交給當前控件所屬的GUI線程去處理。下面簡單舉一個不斷更新GUI界面標籤 lbValue 值的實現步驟:線程
private void SetLBValue(int count);指針
根據以上函數能夠定義一個簡單的委託 delegate void ChangeValueHandler(int count);
private void SetLBValue(int count)
{
this.lbValue.Text = string.Format("當前值:{0}", count);
}
// 開始更新的線程
private void button1_Click(object sender, EventArgs e)
{
new Thread(run).Start();
}
private void run()
{
int count=0;
while (true)
{
this.lbValue.Invoke(new ChangeValueHandler(SetLBValue), count++);
}
}
以上的代碼還有值得回味的地方,後續補充完整!