C# 前台线程和后台线程

进程会等待所有的前台线程完成后再结束本工作;但是如果只剩下后台线程,则会直接结束本工作,不会等待后台线程完成后再结束本工作。

1 new Thread创建的线程

默认情况下使用new Thread()方法创建的线程为前台线程,可以通过手动设置IsBackground属性来创建一个后台线程;

默认前台线程示例:

        #region Thread前后台线程测试
        public static void BackGroundTest()
        {
            var thread1=new Thread(() => {
                while (true)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(string.Format("thread id :{0}  is background:{1}",Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsBackground));
                }
            });

            // new Thread创建的线程默认为前台线程,会一直运行直到结束
            thread1.Start();
        }
        #endregion

测试代码如下:

        static void Main(string[] args)
        {
            ThreadTest.BackGroundTest();

            Console.WriteLine(string.Format("Main  thread id :{0}  is background:{1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsBackground));

            Console.WriteLine("Main Ok");
        }

运行结果:

 

 

 

把线程修改为后台线程测试,后台线程代码如下:

 

 

这时候,再重新运行测试代码,会发现,Main方法运行完后程序后立即退出结束,因为这时候只有一个前台线程即Main方法,当Main方法执行完后,会立即结束所有的后台线程的执行;

2 线程池

C#线程池中的工作线程默认都是后台线程,这意味着当所有的前台线程完成后,所有的后台线程将停止工作;但是可以通过设置修改为前台线程

Thread.CurrentThread.IsBackground = false;

        public static void ThreadPooMethod()
        {
            ThreadPool.QueueUserWorkItem((p) =>{
                while (true)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(string.Format("thread id :{0}  is background:{1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsBackground));
                }
            });
        }

主线程测试代码如下:

        static void Main(string[] args)
        {
            ThreadPoolTest.ThreadPooMethod();

            Console.WriteLine(string.Format("Main  thread id :{0}  is background:{1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsBackground));

            Thread.Sleep(3 * 1000);

            Console.WriteLine("Main Ok");
        }

程序的运行结果是:线程池里的ThreadPooMethod运行了3秒钟后,程序会结束运行,因为作为唯一前台线程的主线程只会运3秒,Main方法运行结束后线程池里的工作线程会停止运行;

3 Task

对于使用任务Task,一般来说是使用线程池作为后台线程;

        public static void BackGroundTest()
        {
            var task1=Task.Factory.StartNew(() => {
                while (true)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(string.Format("thread id :{0}  is background:{1},is ThreadPool :{2}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsBackground,Thread.CurrentThread.IsThreadPoolThread));
                }
            }
            );
        }

 

 由于默认在线程池里作为后台线程运行,所以当所有前台线程运行完后,该工作线程也会立即结束

可以使用Thread.CurrentThread.IsBackground = false;改为前台线程

 

 这时运行结果如下:

 

 程序会一直运行下去。

 

posted @ 2020-11-14 21:24  温故纳新  阅读(4096)  评论(1编辑  收藏  举报