C# Thread.Abort方法与ThreadAbortException异常(取消线程与异常处理)

1、Abort当前线程,后续程序不会执行

class Program
{
    public static Thread thread1;

    static void Main(string[] args)
    {
        thread1 = new Thread(Method1);
        thread1.Start();
        Console.ReadKey();
    }
    public static void Method1()
    {
        try
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Mthod1: " + i.ToString());
                Thread.Sleep(1000);
                if (i == 3)
                {
                    Thread.CurrentThread.Abort();   // 抛出的ThreadAbortException异常
                }
                Console.WriteLine("Mthod1: " + i.ToString() + " End");
            }
        }
        catch (SocketException ex)
        {
            Console.WriteLine("Method1 SocketException: " + ex.ToString());
        }
        catch (ThreadAbortException ex)
        {
            // ThreadAbortException要在Exception的前面,因为Exception能够匹配所有异常
            Console.WriteLine("Method1 ThreadAbortException: " + ex.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine("Method1 Exception: " + ex.ToString());
        }
        finally
        {
            Console.WriteLine("Method1 Finally:");
        }
    }

}

执行结果:

1、thread1.Abort()执行后会直接抛出ThreadAbortException异常。

2、异常会停止后续所有程序的执行(没有输出"Method1: 3 End")。

3、catch语句会执行。catch (Exception ex)和catch (ThreadAbortException ex)都可以捕获异常,由于Exception可以匹配所有异常,因此catch (ThreadAbortException ex)应该在catch (Exception ex)的前面使用,所以输出了“"Method1 ThreadAbortException”。

4、finally语句会执行。

2、Abort当前线程,进行try catch捕获异常

class Program
{
    public static Thread thread1;

    static void Main(string[] args)
    {
        thread1 = new Thread(Method1);
        thread1.Start();
        Console.ReadKey();
    }

    public static void StopMethod1()
    {
        try
        {
            thread1.Abort();                 // 首先捕获抛出的ThreadAbortException异常
        }
        catch (Exception ex)
        {
            Console.WriteLine("StopMethod1: " + ex.ToString());
        }
    }
    public static void Method1()
    {
        try
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Mthod1: " + i.ToString());
                Thread.Sleep(1000);
                if (i == 5) StopMethod1();  // 再次捕获抛出的ThreadAbortException异常
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Method1: " + ex.ToString());
        }
    }
}

运行结果:

try catch{} 捕获两次抛出的ThreadAbortException。

2、Abort当前线程,不进行try catch捕获异常

class Program
{
    public static Thread thread1;

    static void Main(string[] args)
    {
        thread1 = new Thread(Method1);
        thread1.Start();
        Console.ReadKey();
    }

    public static void StopMethod1()
    {
        thread1.Abort();
    }
    public static void Method1()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Mthod1: " + i.ToString());
            Thread.Sleep(1000);
            if (i == 5) StopMethod1();
        }
    }
}

运行结果:

1、虽然线程抛出了ThreadAbortException异常,由于线程中没有使用try catch的语句捕获异常,所以看上去线程很平静的退出了。

2、而且,由于是在线程中抛出的异常,所以主进程没有任何错误提示。

3、for循环只输出到5,Abort()后一般线程会直接停止。

3、在一个线程中Abort另一个线程

class Program
{
    public static Thread thread1;
    public static Thread thread2;

    static void Main(string[] args)
    {
        thread1 = new Thread(Method1);
        thread2 = new Thread(Method2);
        thread1.Start();
        thread2.Start();
        Console.ReadKey();
    }

    public static void StopMethod1()
    {
        try
        {
            thread2.Abort();
        }
        catch (Exception ex)
        {
            Console.WriteLine("StopMethod1: " + ex.ToString());
        }
    }
    public static void Method1()
    {
        try
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Method1: " + i.ToString());
                Thread.Sleep(1000);
                if (i == 5) StopMethod1();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Method3: " + ex.ToString());
        }
    }
    public static void Method2()
    {
        try
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Method2: " + i.ToString());
                Thread.Sleep(1000);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Method2: " + ex.ToString());
        }
    }
}

运行结果:

1、可以看到只在thread2中捕获到了ThreadAbortException异常。

2、thread1完整的运行完毕了,并且没有ThreadAbortException异常抛出。

总结

1、theadX.Abort()方法会在线程X中抛出ThreadAbortException异常,线程X中所有正在执行的try catch都会捕获该异常。

2、theadX.Abort()有可能在Y线程中调用的,不会在Y线程中抛出ThreadAbortException异常。

原文地址:https://www.cnblogs.com/rainman/p/11782401.html

时间: 2024-08-02 17:54:32

C# Thread.Abort方法与ThreadAbortException异常(取消线程与异常处理)的相关文章

注意!你的Thread.Abort方法真的让线程停止了吗?

大家都知道在C#里面,我们可以使用 Thread.Start方法来启动一个线程,当我们想停止执行的线程时可以使用Thread.Abort方法来强制停止正在执行的线程,但是请注意,你确定调用了Thread.Abort方法后线程就立刻停止了吗? 答案是:不是! 下面我们来解释一下Abort方法是如何工作的.因为公用语言运行时管理了所有的托管的线程,同样它能在每个线程内抛出异常.Abort方法能在目标线程中抛出一个ThreadAbortException异常从而导致目标线程的终止.不过Abort方法被

C#如何优雅地取消一个流程(非Thread.Abort方法)

一. Thread.Abort() 的缺点 我们使用 Thread.Abort() 来中止一个包裹着某个流程的线程,虽然 C# 并不会像 Thread.Suspend() 提示过时.但是在使用 Thread.Abort() 的时候,确实存在很多的问题: 1. 该方式中止线程是通过在线程执行的时候抛出 ThreadAbortException 异常来实现的.这边抛出的 ThreadAbortException 异常,不一定可以被局部的程序异常处理程序准确地捕获,而会被抛出在全局,需要通过 AppD

JAVA下的Thread.sleep方法一定要try

try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } 不同于C#,JAVA里的Thread.sleep方法一定有异常

【异常记录(九)】 System.Threading.ThreadAbortException: 正在中止线程

报错如下: System.Threading.ThreadAbortException: Thread was being aborted. at System.Threading.Thread.AbortInternal() at System.Threading.Thread.Abort(Object stateInfo) at System.Web.HttpResponse.End() 可以 try-catch 一下具体线程报错: catch (ThreadAbortException)

Response.End抛出ThreadAbortException 异常

最近在写程序过程中遇到了一个匪夷所思的错误:Response.End()方法抛出了ThreadAbortException异常,我的代码如下: public void doResponse(){ string username=Request.Params["username"]; string password=Request.Params["password"]; try{ var result=bo.doValidateUserInfo(username,pa

Thread interrupt() 方法的使用

原文地址:http://blog.csdn.net/biangren/article/details/7522583 interrupt()只是改变中断状态而已:       interrupt()不会中断一个正在运行的线程.这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态.更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException)

Laravel 5.1 中的异常处理器和HTTP异常处理 abort()

原文  http://laravelacademy.org/post/1867.html 错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器中(出于安全考虑),这个时候我们仍然要捕获异常,只不过不是显示到浏览器中,而是记录到日志中,方便日后排查问题. Laravel当然支持PHP原生的错误和异常处理,但是在此基础上进行了一些封装处理,从而更方便在不

04 Thread的方法(源代码) 和 线程的状态

  1 .Thread中重要的属性 1 publicclass Thread implements Runnable { //继承自Runnable接口private char name[]; // 以char数组保存线程的名字 2 private int priority; // 线程优先级别 3 /* Whether or not the thread is a daemon thread. */ 4 private boolean daemon = false; //是否为守护线程 5 /

Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程

一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. ? threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程对象. # threading.enumerate(): 返回一个包含正在运行的线程的list.正在运行指线程启动后.结束前,不包括启动前和终止后的线程. # threading.activeCount(