C#夯实基础之多线程二:主线程、前台线程与后台线程

      咱们在C#夯实基础之多线程一:初识多线程》一文中第二部分中指出,既然windows最终发展出了多线程模型,按理说,咱们直接使用一个.NetFramework的线程类就能够直接撸代码了,但在这以前,咱们还须要认识一下线程的一些基本特性,它们的出现并非多余的,而是为了解决一部分问题出现的,毕竟存在即合理,咱们先说主线程、前台线程和后台线程:html

一.主线程、前台线程与后台线程编程

   相信前几年,你们都用过迅雷,用来下载文件是很是方便的,更重要的是速度快。那么,它的速度很是之快,全速下载的时候明显地拉慢了整个系统的响应时间,说明他占用了大量的系统资源。那它为何这么快?知乎上的yskin用户解释说一个下载任务进来,迅雷把文件平分红10份,而后开10个线程分别下载。这时主界面是一个单独的线程,并不会由于下载文件而卡死。并且主线程能够控制下属线程,好比某个线程下载缓慢甚至中止,主线程能够把它强行关掉并重启另一个线程。 这么多线程同时工做,正常状况下,下载速度会有质的提高。 windows

   那么,问题来了,当我暂停这个下载任务时,后面10个线程会关掉,但界面线程关闭掉这10个线程的时候,咱们并没有察觉,它们在后台悄默声地就关掉了。这10个线程就是咱们说的后台线程 多线程

如今,咱们把迅雷软件退出了,那么全部的下载任务都关掉了,下载任务背后的线程天然也会关掉,这个迅雷软件运行的线程就是咱们说的主线程,它是一个前台线程 spa

但当咱们再在网页中从新找到可下载的内容时,迅雷的资源嗅探又能够检测到这些内容,交提示咱们是否要下载。它不随着前面迅雷软件的退出而退出。 操作系统

   若是你以为这个例子很差理解,《C#高级编程》中也有一个,当你使用word来编辑文档时,它会实时提供一些拼写检查,当你须要打印文档时,能够选择后台打印,在打印机打印文档的同时,你能够继续编辑当前文档。同时word文档关闭时,这个打印任务可继续执行,直到打印出来,但拼写检查任务不会再执行。 线程

这就是主线程、前台线程与后台线程的一些类比。下面,咱们来讲结论。 code

   当一个程序启动时,就有一个进程被操做系统(OS)建立,与此同时一个线程也马上运行,该线程一般叫作程序的主线程Main Thread),由于它是程序开始时就执行的,若是你须要再建立线程,那么建立的线程就是这个主线程的子线程,它是前台线程。 htm

   新建的子线程能够是前台线程或者后台线程,前台线程必须所有执行完,即便主线程关闭掉,这时进程仍然存活。后台线程在未执行完成时,若是前台线程关掉,则后台线程也会停掉,且不抛出异常。也就是说,前台线程与后台线程惟一的区别是后台线程不会阻止进程终止。能够在任什么时候候将前台线程修改成后台线程。blog

二.C#中的前台线程与后台线程

   C#中,Thread类默认建立的是前台线程,经过线程池(后面会讲到)建立的线程都是后台线程。

       1.建立前台线程和后台线程

 1 static void Main(string[] args)
 2 {
 3     //当前主线程是个前台线程,且不能修改成后台线程
 4     Console.WriteLine(Thread.CurrentThread.IsBackground);
 5 
 6 //Thread建立的线程是前台线程
 7 Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
 8     Console.WriteLine(th.IsBackground);
 9 
10     //Task使用程序池建立线程,默认为后台线程
11     Task task = new Task(() => Console.WriteLine("start a new task"));
12 
13     Console.Read();
14 }

       输出结果:

   

      2.修改前台线程为后台线程

 1 static void Main(string[] args)
 2 {
 3     //修改前台线程为后台线程
 4     Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
 5     Console.WriteLine(th.IsBackground);
 6     th.Start();
 7     th.IsBackground = true;
 8     Console.WriteLine(th.IsBackground);
 9 
10     Console.Read();
11 }

     输出结果

     

     C#中,前台线程能够修改成后台线程,这是由HostProtectionAttribute属性的SelfAffectingThreading字段决定的,若是能够变成后台线程,则值为true.

    3.前台线程阻止进程的关闭

static void Main(string[] args)
 {
     //前台线程阻止了主线程的关闭
     Thread th = new Thread(delegate()
     {
         Thread.Sleep(6000);
         Console.WriteLine("start a new thread");

     });
     th.Start();

     Console.WriteLine("main thread end");
 }

     输出结果:这里主线程立刻执行完成,并不立刻关闭,前台线程等待6秒再执行输出

     

     4.后台线程不阻止进程的关闭

 1 static void Main(string[] args)
 2 {
 3     //后台线程不阻止主线程的关闭
 4     Thread th = new Thread(delegate()
 5     {
 6         Thread.Sleep(6000);
 7         Console.WriteLine("start a new thread");
 8 
 9     });
10     th.IsBackground = true;
11     th.Start();
12 
13     Console.WriteLine("main thread end");
14 }

    结果:不等线程执行完成,主线程执行完毕后自动退出。

三.参考文档

   http://technet.microsoft.com/zh-cn/library/system.threading.thread.isbackground

相关文章
相关标签/搜索