c# Thread.Abort()和Thread.ResetAbort()的使用

c# Thread.Abort()和Thread.ResetAbort()的使用

Thread類的Abort()方法用於終止正在運行的線程(.net core中Abort()方法雖然存在,但是調用它會引發PlatformNotSupportedException的異常提示)。它可以強行終止線程,而不管線程是否是sleep中。
執行了Abort()後,被終止的線程就會繼續運行catch{}finally{}塊中代碼,因爲是強行終止,catch塊之後的語句則不再運行。除非在catch語句中執行Thread.ResetAbort()這個靜態方法。
先舉例沒有ResetAbort()的情況:

using System;
using System.Threading;

class Test
{
    public static void Main()
    {
        Thread newThread = new Thread(new ThreadStart(TestMethod));
        newThread.Start();
        Thread.Sleep(1000);

        // Abort newThread.
        Console.WriteLine("Main aborting new thread.");
        newThread.Abort("Information from Main.");

        // Wait for the thread to terminate.
        newThread.Join();
        Console.WriteLine("New thread terminated - Main exiting.");
    }

    static void TestMethod()
    {
        try
        {
            while (true)
            {
                Console.WriteLine("New thread running.");
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException abortException)
        {
            Console.WriteLine((string)abortException.ExceptionState);
        }
        finally
        {
        	Console.WriteLine("Do somthing else in funally{}.");
        }
        Console.WriteLine("Do somthing else here.");
    }
}
/*輸出結果:
New thread running.
Main aborting new thread.
Information from Main.
Do somthing else in funally{}.
New thread terminated - Main exiting.
*/

看輸出結果,可以看到線程被Abort之後,執行catch和finally塊中的內容,但是不會執行finally塊之後的內容。
再看增加ResetAbort()的代碼:

using System;
using System.Threading;

class Test
{
    public static void Main()
    {
        Thread newThread = new Thread(new ThreadStart(TestMethod));
        newThread.Start();
        Thread.Sleep(1000);

        // Abort newThread.
        Console.WriteLine("Main aborting new thread.");
        newThread.Abort("Information from Main.");

        // Wait for the thread to terminate.
        newThread.Join();
        Console.WriteLine("New thread terminated - Main exiting.");
    }

    static void TestMethod()
    {
        try
        {
            while (true)
            {
                Console.WriteLine("New thread running.");
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException abortException)
        {
            Console.WriteLine((string)abortException.ExceptionState);
            Thread.ResetAbort();
        }
        finally
        {
        	Console.WriteLine("Do somthing else in funally{}.");
        }
        Console.WriteLine("Do somthing else here.");
    }
}
/*輸出結果:
New thread running.
Main aborting new thread.
Information from Main.
Do somthing else in funally{}.
Do somthing else here.
New thread terminated - Main exiting.
*/

從結果中可以看到,線程被終止了,由於執行了Thread.ResetAbort(),因此就允許繼續執行finally塊之後的代碼。
注意: 如果Thread.ResetAbort()語句放在catch塊中,最好應當把Thread.ResetAbort()語句放在catch{}代碼塊最後,否則會把abortException.ExceptionState中的內容給清空了。Thread.ResetAbort()還可以放在finally塊中,它同樣也可以允許繼續執行finally塊之後的代碼。另外,Thread.ResetAbort()只能執行一次,不能執行二次及以上,否則會出新的異常。

現在解釋一下,在默認(不調用Thread.ResetAbort())的情況下, finally塊後的代碼是執行不到的,這是由於 ThreadAbortException這個異常非常特殊,它會在finally塊的最後(如果沒有finally塊,則是在catch塊的最後)重新扔出一個 ThreadAbortException異常。(不過這個異常在外部抓不到,它僅僅是爲了退出線程用的)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章