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异常。(不过这个异常在外部抓不到,它仅仅是为了退出线程用的)。

posted on 2021-05-08 10:26  funiyi816  阅读(466)  评论(0编辑  收藏  举报

导航