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

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

相信前几年,大家都用过迅雷,用来下载文件是非常方便的,更重要的是速度快。那么,它的速度非常之快,全速下载的时候明显地拉慢了整个系统的响应时间,说明他占用了大量的系统资源。那它为什么这么快?知乎上的yskin用户解释说『一个下载任务进来,迅雷把文件平分成10份,然后开10个线程分别下载。这时主界面是一个单独的线程,并不会因为下载文件而卡死。而且主线程可以控制下属线程,比如某个线程下载缓慢甚至停止,主线程可以把它强行关掉并重启另外一个线程。 』这么多线程同时工作,正常情况下,下载速度会有质的提升。

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

现在,我们把迅雷软件退出了,那么所有的下载任务都关掉了,下载任务背后的线程自然也会关掉,这个迅雷软件运行的线程就是我们说的主线程,它是一个前台线程

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

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

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

当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序开始时就执行的,如果你需要再创建线程,那么创建的线程就是这个主线程的子线程,它是前台线程。

新建的子线程可以是前台线程或者后台线程,前台线程必须全部执行完,即使主线程关闭掉,这时进程仍然存活。后台线程在未执行完成时,如果前台线程关掉,则后台线程也会停掉,且不抛出异常。也就是说,前台线程与后台线程唯一的区别是后台线程不会阻止进程终止。可以在任何时候将前台线程修改为后台线程。

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

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

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

 static void Main(string[] args)
{
//当前主线程是个前台线程,且不能修改为后台线程
Console.WriteLine(Thread.CurrentThread.IsBackground); //Thread创建的线程是前台线程
Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
Console.WriteLine(th.IsBackground); //Task使用程序池创建线程,默认为后台线程
Task task = new Task(() => Console.WriteLine("start a new task")); Console.Read();
}

输出结果:

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

 static void Main(string[] args)
{
//修改前台线程为后台线程
Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
Console.WriteLine(th.IsBackground);
th.Start();
th.IsBackground = true;
Console.WriteLine(th.IsBackground); Console.Read();
}

输出结果

在C#中,前台线程可以修改为后台线程,这是由HostProtectionAttribute属性的SelfAffectingThreading字段决定的,如果可以变成后台线程,则值为true.

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

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

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

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

 static void Main(string[] args)
{
//后台线程不阻止主线程的关闭
Thread th = new Thread(delegate()
{
Thread.Sleep();
Console.WriteLine("start a new thread"); });
th.IsBackground = true;
th.Start(); Console.WriteLine("main thread end");
}

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

三.参考文档

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

C#夯实基础之多线程二:主线程、前台线程与后台线程的更多相关文章

  1. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  2. C#夯实基础之多线程三:线程的优先级

    一.为什么需要优先级--线程调度的问题 在现实生活中,优先级是一个很常见的现象:在火车站,如果你是孕妇,你是可以走进站中的专门绿色通道的,可以提前上火车以免拥挤:火警119匪警110出警的时候,都是人 ...

  3. java基础之多线程二:多线程实现方式

    方式一: 继承Thread类. /* * main函数也叫主函数(也叫主线程), * 因为所有代码的执行都是从这里开始的. */ public static void main(String[] ar ...

  4. JavaScript夯实基础系列(二):闭包

      在JavaScript中函数是一等公民.所谓一等公民是指函数跟其他对象一样,很普通,可以进行把函数存在数组中.作为参数传递.赋值给变量等操作.当函数作为另一个函数的返回值在外部调用时,跟该函数在函 ...

  5. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  6. 黑马程序员——【Java基础】——多线程

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)进程 正在执行中的程序,每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控 ...

  7. C#线程学习笔记一:线程基础

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/18/Thread.html,记录一下学习过程以备后续查用. 一.线程的介绍 进程(Proce ...

  8. java之多线程 二

    线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...

  9. Java多线程——<五>后台线程(daemon)

    一.后台线程(守护线程) 学一个东西,最重要的一点就是,为什么要用它? 后台线程区别于普通线程,普通线程又可以称为用户线程,只完成用户自己想要完成的任务,不提供公共服务.而有时,我们希望编写一段程序, ...

随机推荐

  1. 【swift学习笔记】五.使用枚举优雅的管理Segue

    在做页面转跳的时候,我们要给Segue命名,如果Segue多了,管理他们就是一个恶梦.我们可以枚举更优雅的管理这些Segue. 1.我们先来建立一个protocol,他的功能就是让实现类实现一个Seg ...

  2. Android,ios,WP三大手机系统对比

    从前,我以为.一个手机系统只是一个系统的UI风格,没什么不同的.然而,在我混合使用这三个手机系统之后,才明白,一个手机系统远不只一个UI那么简单,而真的是可以称之为一个“生态”. 首先祭出三台经典设备 ...

  3. HttpHelper

    /// <summary> /// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理 /// 重要提 ...

  4. 第六次团队作业——Alpha冲刺之事后诸葛亮

    Deadline:2016-11-24 22:00pm Alpha冲刺,很多同学经历了"Learning by doing"的学一门新的编程语言.学Git.学做一个完整的项目.但是 ...

  5. ABP模块化

    基于Abp模块化.插件化的设计,开发人员可以将自定义的功能以模块的形式集成到项目中. 模块的加载 模块: 插件: 模块及插件的加载路线: 1. 扩展的HttpApplication对象(在Abp.We ...

  6. flask-- 基础篇

    flask简介: flask是一轻量级的web应用框架,它的实现是一个 wsgi 的微("Micro")框架,当然微("Micro")也不意味这它的功能存在不足 ...

  7. linux安装maven

    一.下载maven 最新地址在:http://maven.apache.org/download.cgi 我下载的是:apache-maven-3.3.9-bin.tar.gz,是已经编译好的包 解压 ...

  8. Chrome 开发工具之Elements

    友情提示:全文图片高能,如使用手机阅读,请确保在wifi情况下或者流量充足.图片有点渣,也算辛苦做出来的,请别嫌弃- Elements面板主要展示当前页面的组织结构,在如今的应用程序中,HTML页面初 ...

  9. css3 背景渐变

    本来想先瞎扯些什么,然后又不知道讲什么的好,那就直接进入正题吧. 参考资料: Using CSS gradients  (以及该页面内的大部分链接页面的资料) 首先区分下,平常给的纯色backgrou ...

  10. logistic regression与SVM

    Logistic模型和SVM都是用于二分类,现在大概说一下两者的区别 ① 寻找最优超平面的方法不同 形象点说,Logistic模型找的那个超平面,是尽量让所有点都远离它,而SVM寻找的那个超平面,是只 ...