首頁  >  文章  >  後端開發  >  C#執行緒控制的實例詳解

C#執行緒控制的實例詳解

零下一度
零下一度原創
2017-06-23 16:34:032131瀏覽

方案一:

   呼叫執行緒控制方法.啟動: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.  (Thread.Suspend 已被否決。請使用系統中的其他類別線程,如監視器、互斥體、事件和信號量,以同步線程或保護資源。)

因為,無法判斷目前掛起執行緒時它正在執行什麼程式碼。如果在安全權限評估期間掛起持有鎖的線程,則 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;

[]

以上是C#執行緒控制的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn