线程有两种:前台线程和后台线程。
区别是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
主线程退出,不管后台线程有没有执行完,都会把后台线程结束掉:
static void Main(string[] args)
{
Console.WriteLine("程序启动");
Thread thread = new Thread(Worker);
thread.Start();
thread.IsBackground = true;
Console.WriteLine("主线程退出");
//Console.ReadKey();
}
static void Worker() {
Thread.Sleep(1000);
Console.WriteLine("后台线程退出");
}
以上代码运行结果为:
首先通过Thread类创建了一个线程对象,然后通过IsBackground属性指明该线程为后台线程,启动了后台线程,主线程将会继续执行。主线程运行完毕之后就会中止后台线程,然后使整个程序结束运行。所以Worker不会执行。
但是最后有Console.ReadKey();后台线程会执行,因为Console.ReadKey()就是在等待,只要超过1秒即后台线程就会执行Worker。
在真正的开发环境中我们不可能通过加一句Console.ReadKey()来解决主线程退出后台线程还没执行这个问题,当然,我们还有其他的方法。
方法一:将创建的线程设置为非后台线程(前台线程),只需要注释backThread.IsBackground = true即可;其实不设置IsBackground属性,默认为前台线程。只有前台程序全部执行完才会退出程序。所以子线程的代码会被执行,但是这个时候一执行完马上就退出程序了。
代码和运行结果:
方法二:就是使主线程在后台线程执行完毕之后再执行,即使主线程也进入睡眠,且使睡眠时间比后台线程更长
代码和运行结果:
方法三:使用函数Join来实现,确保主线程会在后台线程结束后才开始运行
代码和运行结果:
使用Join的时候,主线程会等待后台线程结束之后才能继续执行。另外Join方法还有一个参数,表示等待多长时间。如果设置了时间,等了这个时间还没执行完就不会再等了。比如这里设置为500,那么就可能等不了子线程的执行了。