zoukankan      html  css  js  c++  java
  • 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/
    关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

  • 相关阅读:
    c# 进程间同步实现
    mysql 中文支持
    堆排序算法详解
    CodeSmith 使用
    东软C#编程规范
    红伞各版key 申请和下载
    sql 添加删除字段
    第一个Hibernate 程序终于测试通过了
    C#下载大文件并实现断点续传
    Ms rdlc 打印
  • 原文地址:https://www.cnblogs.com/jackson0714/p/AbortThread.html
Copyright © 2011-2022 走看看