C# 多線程之線程控制


方案一:

   調用線程控制方法.啟動:Thread.Start();停止:Thread.Abort();暫停:Thread.Suspend();繼續:Thread.Resume();

 

        private void btn_Start_Click(object sender, EventArgs e)
        {
            mThread.Start();  // 開始
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            mThread.Abort();  // 終止
        }

        private void btn_Suspend_Click(object sender, EventArgs e)
        {
            mThread.Suspend();  // 暫停
        }

        private void btn_Resume_Click(object sender, EventArgs e)
        {
            mThread.Resume();  // 繼續
        }

線程定義為:

            mThread = new Thread(() =>
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                }
            });

值得注意的是: 通過 Thread.Abort() 停下來的線程(或自行運行結束的線程),都無法直接通過 Thread.Start() 方法再次啟動,必須重新創建一個線程啟動。

所以,“開始按鈕”事件應為:

        private void btn_Start_Click(object sender, EventArgs e)
        {
            // 定義線程
            mThread = new Thread(() => // Lambda 表達式
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                }
            });

            mThread.Start();  // 開始
        }

此外,對於 Thread.Suspend() 和 Thread.Resume() 方法,微軟已經將其標記為過時:

Thread.Suspend has been deprecated.  Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.  http://go.microsoft.com/fwlink/?linkid=14202(Thread.Suspend 已被否決。請使用系統中的其他類線程,如監視器、互斥體、事件和信號量,以同步線程或保護資源。http://go.microsoft.com/fwlink/?linkid=14202)

因為,無法判斷當前掛起線程時它正在執行什么代碼。如果在安全權限評估期間掛起持有鎖的線程,則 AppDoamin 中的其它線程可能被阻止。如果在線程正執行構造函數時掛起它,則 AppDomain 中嘗試使用該類的其它線程將被阻止。這樣容易發生死鎖。

方案二:

   在 線程運行過程中 適當的位置(如某個完整的功能/命令后)判斷是否要繼續線程,再決定線程的命運。

  1.定義一個全局變量:

        int mTdFlag = 0; // 1:正常運行;2:暫停;3:停止

  2. 定義一個判斷方法:

        bool WaitForContinue()
        {
            if (this.mTdFlag == 3)
            {
                return false; // 返回false,線程停止
            }
            else if (this.mTdFlag == 2)
            {
                while (mTdFlag != 1)
                {
                    Thread.Sleep(200); // 假暫停;停頓時間越短,越靈敏
                    if (this.mTdFlag == 3)
                    {
                        return false; // 返回false,線程停止
                    }
                }
            }
            return true; // 返回true,線程繼續
        }

    3.修改 控制命令 事件:

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 3;
            //mThread.Abort();  // 終止
        }

        private void btn_Suspend_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 2;
            //mThread.Suspend();  // 暫停
        }

        private void btn_Resume_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 1;
            //mThread.Resume();  // 繼續
        }

   4.在線程運行過程中適當的位置,判斷線程是否繼續

            mThread = new Thread(() =>
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                            if (i % 10000000 == 0)
                            {
                                this.textBox1.Text += ".";
                            }
                            if (!WaitForContinue()) // 返回 false 則,停止
                            {
                                break;
                                //return;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        if (!WaitForContinue()) // 返回 false 則,停止
                        {
                            break;
                            // return;
                        }
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                    this.textBox1.Text += ex.Message + "...";
                }
                finally
                {
                    this.textBox1.Text += "線程已結束";
                }
            });

 

在窗體中,解決跨線程訪問問題:在窗體構造函數中添加代碼:  Control.CheckForIllegalCrossThreadCalls = false;

 

[http://www.cnblogs.com/CUIT-DX037/]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM