多线程启动停止暂停继续

描述

  前言

  初学者学习编程时,很容易因为多线程出现各种问题,导致不敢使用多线程。但是多线程技术在做开发中,是不可忽视的一个技术,基本上我们实际应用中,每个项目都会使用多线程,所以多线程技术必须掌握。

  为什么要用多线程

  随着工业的进步,现在的笔记本、台式机大都是双核的,4核、8核甚至16核,也很常见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。

  单核CPU上所谓的”多线程”那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程”同时”运行罢了。

  多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。

  如果你做项目不使用多线程,不仅是技术的问题,也是对电脑资源的极大浪费,就像你买了一辆配置非常高的越野车,你仅仅只用它来日常代步一样。3

  为什么不敢用多线程

  之前跟一些学员沟通时发现,很多学员之所以不敢使用多线程,是因为之前出过问题,有种“一朝被蛇咬,十年怕井绳”的感觉。

  为什么多线程容易出问题,有个主要的原因在于多线程充满着“未知性”,有的人使用时,发现代码并没有按照预想的流程在走,这其实是正常的。

  我们必须要明确一点,多线程确实是“不可控的”,有某种意义上来说,多线程是靠CPU调度来执行的,并非人为去控制。

  我们所谓的控制多线程,仅仅是.NET框架开放了一些接口给开发者,这样可以相对性地间接控制多线程的启动停止暂停继续。

  线程的启动停止

  线程的启动停止,从.Net Framework 4.5开始,Task提供了一个叫CancellationTokenSource的对象,可以使用它来对多线程的启停进行控制。

  首先,我们做一个线程任务,这个任务很简单,只是不断操作某个变量,每0.1秒加1,到一定值之后,重置为0,然后将这个值显示在界面上,界面如下所示:

  

多线程

  所以任务方法如下:

  

多线程

  个对象就是CancellationTokenSource的对象,因此我们需要创建一个CancellationTokenSource对象cts:

  

多线程

  然后在启动线程按钮的事件里,编写代码如下:

  

多线程

  停止线程按钮的事件里,只需要调用cts的Cancel方法即可:

  

多线程

  其实,说白了,就是通过cts来控制cts的IsCancellationRequested属性,进而实现多线程的控制。

  线程的暂停继续

  多线程的暂停继续,.NET为我们提供了另外一个对象——ManualResetEvent,这个对象会有一个值,这个值是布尔类型,就像一个门闸一样,True是打开门闸,False是关闭门闸,所以想要暂停多线程就调用这个对象的Reset方法,想要继续多线程就调用这个对象的Set方法,使用非常简单。

  首先我们创建一下这个对象,可以通过构造方法,给这个对象赋初始值,我这里为True,这样就能直接运行,不会阻塞。

  

多线程

  但是如果希望这个对象与多线程有所联系,必须要在多线程的方法里体现这个对象的作用,这个是调用这个对象的WaitOne方法,表示在调用的地方阻塞住,通过判断True或者False来决定是否继续执行,就像大家开车过高速收费站一样,即使现在普遍采用ETC了,在入口也需要减速,有一个ETC识别的过程,识别成功才会抬杆,识别识别,杆子是不会自动抬起的,这个是一样的道理。

  所以线程执行代码如下:

  

多线程

  对比一下,其实就是加了一个manual.WaitOne()。

  线程暂停代码:

  

多线程

  线程继续代码:

  

多线程

  AutoResetEvent

  AutoResetEvent和ManualResetEvent的用法非常相似,区别在于一个是手动,一个是自动,AutoResetEvent会在置位之后自动复位,这样体现在多线程里,就是会只执行一次,就像大家进小区一样,如果有10辆车在排队,这时候如果自动模式,每次只能进一辆车,如果是手动模式,可以由保安控制门闸打开,等10辆车都进去之后,再由保安将门闸关注。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分