C#多線程之旅(7)——終止線程


先交代下背景,寫《C#多線程之旅》這個系列文章主要是因為以下幾個原因:1.多線程在C/S和B/S架構中用得是非常多的;2.而且多線程的使用是非常復雜的,如果沒有用好,容易造成很多問題。

 

原文地址:C#多線程之旅(7)——終止線程 (原創:博客園-Jackson0714)

C#多線程之旅目錄:

C#多線程之旅(1)——介紹和基本概念

C#多線程之旅(2)——創建和開始線程

C#多線程之旅(3)——線程池

C#多線程之旅(4)——APM初探

C#多線程之旅(5)——同步機制介紹

C#多線程之旅(6)——詳解多線程中的鎖

 C#多線程之旅(7)——終止線程

更多文章正在更新中,敬請期待......

一、什么時候用Thread.Abort();

當我們想要立即終止一個線程時,可以用調用Thread.Abort方法來終止線程。這個和協作式取消不一樣。

終止當前線程時會在當前線程上引發ThreadAbortException 異常。ThreadAbortExcetion是一個可以被應用程序捕獲的特殊異常,在catch 塊中會自動重新拋出這個異常,除非在catch塊中調用ResetAbort方法。ResetAbort方法可以取消掉終止的請求,而且可以防止catch中再次拋出的ThreadAbortException終止當前線程。未執行的Finally塊會在線程終止前執行。

二、Thread.Abort的用法

例子:

 

名稱

代碼

計算限制的

操作

public class ThreadWork
{
    public static void DoWork()
    {
        try
        {
            for (int i = 0; i < 100; i++)
            {
                Tool.WriteMessage("Thread - working.", ConsoleColor.Green, ConsoleColor.White);
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException e)
        {
            Tool.WriteMessage("Thread - Caught ThreadAbortException - resetting.", ConsoleColor.Green, ConsoleColor.White);
            Tool.WriteMessage("Thread - Exception message: " + e.Message, ConsoleColor.Red, ConsoleColor.White);
            
            /*--如果調用Thread.ResetAbort()-----
            1.取消終止線程的請求,並恢復線程,繼續執行ResetAbort后面的語句,然后執行catch塊之后的語句
            2.若Catch塊之后有Finally塊,則執行Finally塊,然后執行Finally塊后面的語句。
            */
            /*----如果沒有調用Thread.ResetAbort()----
            1.finally塊在線程終止前執行,finally塊之后的語句不會被執行,然后線程終止。
            */
            //Thread.ResetAbort();
            //Tool.WriteMessage("Thread - ResetAbort", ConsoleColor.Green, ConsoleColor.White);
        }
        finally
        {
            Tool.WriteMessage("Thread - Finally blocks were executed.", ConsoleColor.Green, ConsoleColor.White);
        }
        Tool.WriteMessage("Thread - still alive and working.", ConsoleColor.Green, ConsoleColor.White);
        Thread.Sleep(1000);
        Tool.WriteMessage("Thread - finished working.", ConsoleColor.Green, ConsoleColor.White);
    }
}

主程序

public class ThreadAbortTest
{
    public static void Main()
    {
        try
        {
            ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork);
            Thread myThread = new Thread(myThreadDelegate);
            myThread.Start();//啟動線程myThread,執行DoWork方法
            Thread.Sleep(100);
            Tool.WriteMessage("Main - aborting my thread.", ConsoleColor.Blue, ConsoleColor.White);
            myThread.Abort();//終止線程myThread
            myThread.Join();//等待線程myThread結束
            Tool.WriteMessage("Main - ending.", ConsoleColor.White, ConsoleColor.White);
        }
        catch(Exception ex)
        {
            throw ex;
        }
        Console.ReadKey();
    }
}

工具類

public static class Tool
{
    public static void WriteMessage(string message, ConsoleColor writeColor ,ConsoleColor backColor)
    {
        Console.ForegroundColor = writeColor;
        Console.WriteLine(message);
        Console.ForegroundColor = backColor;
    }
}

 

(1)調用Thread.Abort()的輸出結果:

 

(2)未調用Thread.Abort()輸出結果:

 

(3)流程:

(1)當主線程調用myThread.Abort()后,線程myThread拋出異常,線程myThread捕獲到異常

(2)在myThread catch塊中

如果調用Thread.ResetAbort()-----

     Step1.取消終止線程的請求,並恢復線程,繼續執行ResetAbort后面的語句,然后執行catch塊之后的語句

     Step2.若catch塊之后有Finally塊,則執行執行Finally塊,然后執行Finally塊后面的語句。

 如果沒有調用Thread.ResetAbort()----

      1.finally塊在線程終止前執行,finally塊之后的語句不會被執行,然后線程終止。

 

三、無法終止線程的情形

當調用線程的Abort方法時,不能保證線程立即終止,有可能永遠不能終止。這種情形發生在catch或finally塊中存在長時間或無限的耗時操作時。

只有當catch或finally塊中代碼執行完才能終止線程。所以我們可以調用線程的Join方法來等待線程的完成或終止。

四、Catch塊中拋出異常

應用程序將會被終止,Finally塊不會被執行

 

五、Finally塊中拋出異常

應用程序將會被終止

 

六、Abort調用的時間

(1)線程Start之前調用Abort

線程會在Start被調用時終止線程。

(2)線程Sleeping的時候調用Abort

線程被中斷,然后終止線程

(3)線程Blocked的時候調用Abort

線程被中斷,然后終止線程

(4)線程被掛起的時候調用Abort

Throw ThreadStartException 引發Abort的調用,然后AbortRequested 被加到正在被終止的線程的ThreadState屬性

(5)一個托管線程正在執行非托管代碼時調用Abort

ThreadAbortException不會被拋出直到線程返回托管代碼。

(6)如果同時Abort兩個線程,有可能一個線程會設置狀態信息,而另外一個線程執行Abort的方法。然而,應用程序不會檢測到這種情形。

 


作  者: Jackson0714
出  處:http://www.cnblogs.com/jackson0714/
關於作者:專注於微軟平台的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角推薦一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!

 


免責聲明!

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



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