1. 程式人生 > >C#中的後臺執行緒

C#中的後臺執行緒

基本概念就不再多說,後臺執行緒和前臺執行緒的主要區別就是後臺執行緒不會防止程序的終止,這句話如何理解呢?下面用個例子來理解一下。      (閱讀時請注意執行緒和程序的區別

先來看一下開啟子執行緒的標準流程:

    public partial class Form1 : Form
    {
        private volatile bool threadStopped;  //多執行緒訪問的變數要用volatile修飾
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {

            Thread t = new Thread(MyThread);
            //t.IsBackground = true;      //設定是否為後臺執行緒
            t.Name = "My Thread";
            t.Start();
            Thread.Sleep(100);
            MessageBox.Show("主執行緒輸出!");
            threadStopped = true;
        }

        private void MyThread()
        {
            MessageBox.Show("輔助執行緒開始!");
            while(!threadStopped)
            {
                Thread.Sleep(10);
            }
            MessageBox.Show("輔助執行緒結束!");
        }
}

在C#程式碼中使用new Thread( )新建的程序預設是前臺執行緒,要想設定為後臺執行緒,那麼只需要將子執行緒的isBackGround屬性設定為true即可。我們一般都會設定一個volatile變數來控制子執行緒是否結束,其實在這段程式碼中不管是否設定為後臺執行緒,程式都可以正常執行,那麼 t.IsBackground = true 什麼時候有作用呢?

答案是這樣的,很多時候一些子執行緒會被設計為死迴圈,也就是形如 while(true) 這樣的,比如掃描執行緒,狀態監測執行緒之類的,這些程序如果沒有被設定為後臺執行緒,那麼程序就無法關閉,因為在沒有強制終止的情況下,屬於程序的所有前臺執行緒都結束後,公共語言執行庫才會結束該程序。

也就是說,如果沒有設定為後臺執行緒,且執行緒的委託方法是如下形式:

        private void MyThread()
        {
            MessageBox.Show("輔助執行緒開始!");
            while(true)
            {
                Thread.Sleep(10);
            }
            MessageBox.Show("輔助執行緒結束!");
        }

就會出現這樣的情況:

我點選關閉視窗後,程序依然沒有終止,除錯按鈕也表示還在執行:


關於volatile修飾符,也挺有意思,並不是只有在多執行緒時才使用,本意是即使程式程式碼沒有對記憶體單元進行修改,其值也有可能發生變化。有可能是硬體修改,也可能是兩個程式互相影響。

但它的本質還是告訴編譯器,不要對該變數進行編譯優化,所謂的編譯優化就是指當編譯器發現程式在幾條語句中多次使用了某變數值,編譯器可能不是每次都去記憶體中查詢該變數,而是將該變數的值快取到暫存器。這樣就不能及時更新真正的值。