zoukankan      html  css  js  c++  java
  • 关于多线程程序完全退出的解决方案

    最近遇到了这个问题,如果程序开了好多线程的话,那么在主线程里调用Application.Exit()函数,发现程序不能完全退出

    image

    msdn关于这个方法的说明,该方法并不强制程序退出,只是强制Run()函数返回,也就是该函数的调用会导致Main()函数的结束,也就是主线程的结束。

    但是整个程序确不会结束(如果还有其他前台线程正在运行,未结束),可以在进程管理器看到进程正在运行。

    百度了一下关于多线程程序强制退出的问题,发现了一个方法觉得好奇怪,与自己以前的认识不一样。作者是这样做的:

    image

    把主线程设置为后台线程,作者认为只要主线程是后台线程并结束的话,那么整个程序就会退出,其他线程也会正常结束。

    那么到底什么事前台和后台线程呢?它们的区别又是什么?《C#高级编程》是这样说的:

    image

    只要有前台线程继续运行,那么应用程序就是激活的即没有退出。只有当所有前台线程运行结束后,不管后台线程是否正在运行,程序都将结束。

    下面我就按照上面那位作者的思路试验一下:

        class Program
        {
            static void Main(string[] args)
            {
                Thread th = new Thread(work);
                th.IsBackground = false;//默认就是前台线程,不写也可以
                  th.Start();
                Thread.CurrentThread.IsBackground = true;//主线程设置成后台线程
                  Console.WriteLine("main thread end ...");
                Console.WriteLine("---------------------\n");
                Thread.Sleep(200);
            }
    
            static void work()
            {
                Console.WriteLine("test thread is starting...");
                for (int i = 0; i < 4; i++)
                {
                    Console.WriteLine(i);
                    Thread.Sleep(1000);
                }
                Console.WriteLine("test thread is end...");
            }
        }
    运行结果如下:

    image

    可以看到,主线程正常退出了,输出了“main thread end …”后,测试线程仍在正常运行并打印了1,2,3,4后结束运行。

    可见,即使讲主线程设置成了后台线程,主线程退出了,只要有前台线程仍在活动状态,那么程序就不会退出。

    那么怎样使用多线程程序在主线程运行结束的时候,使所有线程也运行结束呢??

    试看下面的代码:

        class Program
        {
            static void Main(string[] args)
            {
                for (int i = 0; i < 4;i++ )
                {
                    Thread th = new Thread(work);
                    th.IsBackground = true;//默认就是前台线程,设置成后台线程
                      th.Start(i);             //启动测试线程
                 }      
                Thread.CurrentThread.IsBackground = false;//主线程设置成前台线程,即默认状态
                 Thread.Sleep(500);  //主线程延时500ms,等待测试线程
                 Console.WriteLine("main thread end ...");
            }
    
            static void work(object e)
            {
                int index= (int)e;
                Console.WriteLine("test thread "+index+" is starting...");
                for (int i = 0; i < 4; i++)
                {
                    Console.WriteLine(i);
                    Thread.Sleep(400);
                }
                Console.WriteLine("test thread "+index+" is end...");
            }
        }

    image

           运行结果如左图所示;

           发现只要当主线程运行结束后,不管测试线程(后台线程)有几个是否正在运行程序都会结束运行。

          1.由此可见,只要新启动线程的时候将线程设置成后台线程,主线程默认前台不变,那么当主线程

          退出时,程序将结束运行。

          使用这种方法使程序完全退出,可能会丢失后台线程工作数据,造成程序错误,所有良好的方法   

          是使用某种线程通信机制使主线程即将退出运行前通知所有辅助线程保存状态并结束运行,当所

          有辅助线程结束运行后,主线程退出。(线程通信方法有很多,比如全局变量,线程消息,内核对象等。)

  • 相关阅读:
    文件上传与下载/Mail
    监听器/国际化
    过滤器
    父类转为子类涉及到的安全问题
    连接池
    【MySQL】Windows10下的安装与配置
    【neo4j】关于出现The old parameter syntax `{param}` is no longer supported. Please use `$param` instead的问题
    关于GitHub上传超过100M文件方法
    记录一次在知道创宇公司的实习面试经历
    《机器学习实战(基于scikit-learn和TensorFlow)》第七章内容学习心得
  • 原文地址:https://www.cnblogs.com/sunbing/p/3069064.html
Copyright © 2011-2022 走看看