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