子執行緒與UI執行緒的通訊(委託)

Nincems發表於2018-11-25

轉自:https://www.cnblogs.com/saper/archive/2008/11/11/1331062.html

由於專案中存在這樣的載入的畫面:在介面上有顯示載入資訊的Label控制元件和進度條,如果採用單執行緒則在載入資料的時候UI介面會被鎖死,造成假死的感覺。為了給一個更友好的介面,因此有必要引入多執行緒技術,使得軟體更加“人性化”。

但隨後在子執行緒中訪問介面上的控制元件的時候會出現異常,不能操作主執行緒所控制的UI介面。看來這得用到委託技術了!

首先我們定義委託:

public delegate void loadin(string data, int progress); 

定義委託用delegate關鍵字,隨後跟著一個返回值(這裡void就是沒有返回值了),loadin是委託名,後面帶著兩個引數,分別代表顯示載入的資料和載入進度條的數值!

在窗體的Load事件裡面我們定義一個子執行緒,用於在後臺載入資料並顯示載入情況。

定義執行緒:

ThreadStart ts = new ThreadStart(Downin);  //括號裡面的引數是一個方法名,表示執行緒要處理的方法

Thread mythread = new Thread(ts);    

mythread.Start();   //執行緒開始運作

以上三行是執行緒操作的核心內容,不熟悉執行緒定義和執行原理等的園友請參考《C#執行緒參考手冊》!

然後我們在Downin方法裡面例項化委託並呼叫之。(這裡“例項化”似乎用得不妥,但其實委託和類有很多地方是相似的)

private void Downin()

    {           

        loadin di = new loadin(Update);   //委託後面的引數跟著一個方法名

        this.Invoke(di, "正在初始化系統", 5);    //呼叫委託所關聯的方法,並傳遞兩個引數

        Thread.Sleep(500);                 //執行緒停止工作0.5秒

        this.Invoke(di, "正在載入配置資訊",35);

        Thread.Sleep(500);

        this.Invoke(di, "正在載入使用者資料",70);

        Thread.Sleep(500);

        this.Invoke(di, "正在完成",100);

        Thread.Sleep(500);      

        Thread.CurrentThread.Abort();        //當前執行緒(子執行緒)終止          

    }

委託其實就是充當方法的簽名,這裡委託的引數就是一個方法名,這個方法名帶有兩個引數,和委託參數列是一樣的,同時返回型別也是一樣!

private void Update(string data,int progress)     //在info標籤上顯示載入資訊

    {

        this.info.Text = data.ToString();

        this.progressBar.Value = progress;

 }

就這樣我們繞了一圈,“間接”得通過委託訪問主執行緒構建的控制元件。

本文只是拋磚引玉,可以瞭解一下執行緒和委託的好處。當然,執行緒並不是越多越好,否則只會增加系統開銷,應該看實際需要來應用。

注:如有疏漏之處請指教,謝謝。

原文請見:https://www.cnblogs.com/saper/archive/2008/11/11/1331062.html

相關文章