当前位置: 首页 > news >正文

校园网站建设和管理工作制度中国邮政做特产的网站

校园网站建设和管理工作制度,中国邮政做特产的网站,江西网,西樵网站设计1、简介 虽然ThreadPool、Thread能开启子线程将一些任务交给子线程去承担,但是很多时候,因为某种原因,比如子线程发生异常、或者子线程的业务逻辑不符合我们的预期,那么这个时候我们必须关闭它,而不是让它继续执行,消耗资源.让CPU不在把时间和资源花在没有意义的代码上. 2、主线… 1、简介 虽然ThreadPool、Thread能开启子线程将一些任务交给子线程去承担,但是很多时候,因为某种原因,比如子线程发生异常、或者子线程的业务逻辑不符合我们的预期,那么这个时候我们必须关闭它,而不是让它继续执行,消耗资源.让CPU不在把时间和资源花在没有意义的代码上.   2、主线程取消所有子线程执行的简单代码演示和原理分析 (1)、代码演示 static void Main(string[] args){//显示定义一个取消辅助线程的操作CancellationTokenSource ctsToken new CancellationTokenSource();ThreadPool.QueueUserWorkItem(o EoworkOne(ctsToken.Token));ThreadPool.QueueUserWorkItem(o EoworkTwo(ctsToken.Token));ctsToken.Cancel();Console.Read();}/// summary/// 辅助线程一/// /summary/// param nametoken/paramstatic void EoworkOne(CancellationToken token){//判断主线程是否调用了CancellationTokenSource实例的Cancel方法//相当于判断主线程是否传递给辅助线程一一个取消标记,如果你去看源码,你会发现,里面有个有趣的类Timer,so,你懂的结合之前的文档,可以猜测这个时间很有可能是CPU切换上线文的时间 //每当过了这个时间,该子线程就去判断主线程有没有传递给它取消的信号.当然这只是我的猜测,哈哈if (token.IsCancellationRequested){//如果主线程传递给辅助线程一一个取消操作标记,执行下面的代码Console.WriteLine(主线程调用了Cancel方法,所以辅助线程一获取了主线程取消辅助线程一的标记,但是并不会真正的关闭当前线程);Console.WriteLine(辅助线程一执行return操作,自己显示的退出,那么接下去的方法都不会被执行);return;}}/// summary/// 辅助线程二/// /summary/// param nametoken/paramstatic void EoworkTwo(CancellationToken token){//判断主线程是否调用了CancellationTokenSource实例的Cancel方法//相当于判断主线程是否传递给辅助线程一一个取消标记if (token.IsCancellationRequested){//如果主线程传递给辅助线程一一个取消操作标记,执行下面的代码Console.WriteLine(主线程调用了Cancel方法,所以辅助线程二获取了主线程取消辅助线程二的标记,但是并不会真正的关闭当前线程);}//因为当主线程传递给辅助线程二一个取消标记,但是上面的if语句块,并没有执行return操作,所以下面的语句还是会继续执行Console.WriteLine(辅助线程二获得取消标记操作后,并没有执行显示的return操作,所以辅助线程二继续执行);}   (2)、原理分析  第一步:创建一个CancellationTokenSource对象实例,该对象包含了所有关于取消子线程有关的所有状态 CancellationTokenSource ctsToken new CancellationTokenSource();  第二步:将CancellationTokenSource对象实例的CancellationToken对象实例传递给需要进行取消操作的所有子线程.并且可以通过这个CancellationToken对象实例关联到CancellationTokenSource对象实例. ThreadPool.QueueUserWorkItem(o EoworkOne(ctsToken.Token)); ThreadPool.QueueUserWorkItem(o EoworkTwo(ctsToken.Token));  第三步:当主线程调用CancellationTokenSource对象实例的Cancel方法,所有的子线程通过调用CancellationToken对象实例的IsCancellationRequested属性,该属性定时去获取初始线程(主线程)是否执行了CancellationTokenSource对象实例的Cancel方法,如果调用了,该属性为true。这时可以理解为子线程到主线程的取消信号,可以通过调用return方法来终止子线程的操作. //判断主线程是否调用了CancellationTokenSource实例的Cancel方法//相当于判断主线程是否传递给辅助线程一一个取消标记if (token.IsCancellationRequested){//如果主线程传递给辅助线程一一个取消操作标记,执行下面的代码Console.WriteLine(主线程调用了Cancel方法,所以辅助线程一获取了主线程取消辅助线程一的标记,但是并不会真正的关闭当前线程);Console.WriteLine(辅助线程一执行return操作,自己显示的退出,那么接下去的方法都不会被执行);return;}   3、如果创建一个不能被取消的子线程 通过给子线程传递一个CancellationToken.None实例,该子线程无法被取消,原因很简单,CancellationToken.None实例没有关联的CancellationTokenSource对象实例,所以无法调用Cancel方法显示取消.所以子线程调用token.IsCancellationRequested属性,该属性永远为false.调用token.CanBeCanceled属性也为false. static void Main(string[] args){ThreadPool.QueueUserWorkItem(o EoworkOne(CancellationToken.None));Console.Read();}/// summary/// 辅助线程一/// /summary/// param nametoken/paramstatic void EoworkOne(CancellationToken token){if (token.IsCancellationRequested){//永远无法执行}Console.WriteLine(辅助线程一能被取消吗?{0},token.CanBeCanceled?能:不能);Console.WriteLine(通过CancellationToken.None实例创建的子线程无法被取消);}   4、初始线程(主线程)调用给CancellationTokenSource对象实例的Cancel方法添加回调函数 通过调用CancellationToken实例的Register方法来实现这个功能. static void Main(string[] args){CancellationTokenSource ctsToken new CancellationTokenSource();ThreadPool.QueueUserWorkItem((o eowOne(ctsToken.Token)));ctsToken.Token.Register(() { Console.WriteLine(ctsToken实例调用Cancel方法之后执行的回调函数一); });ctsToken.Token.Register(() { Console.WriteLine(ctsToken实例调用Cancel方法之后执行的回调函数二); });ctsToken.Cancel();Console.Read();}/// summary/// 辅助线程一/// /summarystatic void eowOne(CancellationToken token){Thread.Sleep(2000);//模拟处理需要长时间做的任务Console.WriteLine(辅助线程一做完了它的事);} 通过输出,可以发现,在给CancellationTokenSource实例的Token注册完回调函数后,调用CancellationTokenSource实例的Cancel方法,立刻执行回调函数,但是,主线程并没有等子线程执行完毕,在执行注册的回调.而是直接执行回调。说明线程池线程在管理子线程何时执行完毕是非常无力的.   5、关于处理CancellationTokenSource实例调用Cancel方法后,获取所有回调函数的未处理的异常 (1)、给CancellationTokenSource的Cancel方法传递true static void Main(string[] args){CancellationTokenSource ctsToken new CancellationTokenSource();ThreadPool.QueueUserWorkItem((o eowOne(ctsToken.Token)));ctsToken.Token.Register(() { throw new Exception(回调函数一抛出的异常); });ctsToken.Token.Register(() { throw new Exception(回调函数二抛出的异常); });ctsToken.Cancel(true);Console.Read();}/// summary/// 辅助线程一/// /summarystatic void eowOne(CancellationToken token){Thread.Sleep(2000);//模拟处理需要长时间做的任务Console.WriteLine(辅助线程一做完了它的事);} 调试代码发现,执行到第一个回调函数,抛出异常,程序直接跳出,不再执行第二个函数.所以可以得出结论,为Cancel方法传递true,它只会捕获第一个异常,不再执行第二个异常.   (2)、给CancellationTokenSource的Cancel方法传递false 传递false后,程序会分别执行所有的回调,并抛出一个System.AggregateException异常,回调函数的异常会被追加到到其InnerExceptions属性中.   6、ManualResetEvent、AutoResetEvent阻塞线程信号量使用 关于强制主线程等待子线程完成任务之后执行的方法主要用这两个信号量来实现,注意主线程只能等待一个子线程的完成,不能等待两个子线程完成,这里我试了很多种办法,都不行,可能对它的Api还不够了解.所以用的时候需要考虑这点.使用ManualResetEvent信号量,主线程只能等待一个子线程的完成. 用法如下: (1)、ManualResetEvent static void Main(string[] args){ManualResetEvent mre new ManualResetEvent(false);//创建ManualResetEvent信号量,主线这里构造函数必须传递falseThreadPool.QueueUserWorkItem((o eowOne(mre)));//开启辅助线程mre.WaitOne();//让主线程等待子线程的完成Console.WriteLine(主线程继续做它的事情!);Console.Read();}/// summary/// 辅助线程一/// /summarystatic void eowOne(ManualResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程一做完了它的事,耗时:{0}, watch.ElapsedMilliseconds/1000);mre.Set();//告诉主线程子线程执行完了,如果不给ManualResetEvent实例调用这个方法,主线程会一直等待子线程调用ManualResetEvent实例的Set方法} 如果子线程不调用Set方法,子线程代码如下: /// summary/// 辅助线程一/// /summarystatic void eowOne(ManualResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程一做完了它的事,耗时:{0}, watch.ElapsedMilliseconds/1000);} 子线程做完了它的事情,但是没有调用ManualResetEvent实例的Set方法,所以,主线程会一直等待.这里主线程就被阻塞了. 结论: (1)、当给ManualResetEvent实例的构造函数传false的时候,主线程调用ManualResetEvent实例的WaitOne方法时,如果子线程没有调用ManualResetEvent实例的Set方法,那么主线程会阻塞. (2)、如果子线程调用了ManualResetEvent实例的Set方法,那么主线程调用ManualResetEvent实例的WaitOne方法,那么主线程会接收到一个子线程已经完成的信号,并且继续执行.不会阻塞. (3)、无论怎么样主线程都会阻塞,只是不调用Set,主线程永远阻塞了,执行不下去了,调用Set,主线程还是会阻塞,但是当子线程完成工作之后,它会继续执行.   (2)、ManualResetEvent的ReSet方法 让ManualResetEvent实例回归初始状态 static void Main(string[] args){ManualResetEvent mre new ManualResetEvent(false);//创建ManualResetEvent信号量,主线这里构造函数必须传递falseThreadPool.QueueUserWorkItem((o eowOne(mre)));//开启辅助线程一mre.WaitOne();//让主线程等待辅助线程一的完成mre.Reset();//调用ReSet方法,让ManualResetEvent回到初始状态,如果不使用这个方法,主线程不会等待辅助线程二,直接执行,因为辅助线程一已经调用了mre.Set方法ThreadPool.QueueUserWorkItem((o eowTwo(mre)));//开启辅助线程二mre.WaitOne();//让主线程等待子线程辅助线程二的完成Console.WriteLine(主线程继续做它的事情!);Console.Read();}/// summary/// 辅助线程一/// /summarystatic void eowOne(ManualResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程一做完了它的事,耗时:{0}, watch.ElapsedMilliseconds/1000);mre.Set();}/// summary/// 辅助线程二/// /summarystatic void eowTwo(ManualResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程二做完了它的事,耗时:{0}, watch.ElapsedMilliseconds / 1000);var status mre.Set();if (status){mre.Reset();}} ok,主线程会依次等待两个线程顺序执行完它们的事情,你可能发现一个问题.这和同步有什么区别!哈哈,有区别,如果主线程执行的任务足够耗时,而且执行到某一个时段,需要判断子线程是否完成,获取需要子线程的返回值(当然TreadPool不能很友好的拿到返回值),这个时候这种做法就有优势了两个线程各自承担自己的事情,互不干扰,需要协同操作了,主线程调用下Wait方法,确认子线程正确的完成了它的操作之后,继续执行主线程的任务..所以需谨慎使用.主线程如果啥都不干,光光去等待子线程完成,这种情况和同步就没有删么区别了.所以这个过程可能会卡界面.也有可能不卡.   (3)、AutoResetEvent信号量 AutoResetEvent和ManualResetEvent大体上没什么区别,都是阻塞主线程,但是ManualResetEvent需要每次调用ReSet方法而AutoResetEvent不用. static void Main(string[] args){AutoResetEvent mre new AutoResetEvent(false);//创建ManualResetEvent信号量,主线这里构造函数必须传递falseThreadPool.QueueUserWorkItem((o eowOne(mre)));//开启辅助线程一mre.WaitOne();//让主线程等待辅助线程一的完成ThreadPool.QueueUserWorkItem((o eowTwo(mre)));//开启辅助线程二mre.WaitOne();//让主线程等待子线程辅助线程二的完成Console.WriteLine(主线程继续做它的事情!);Console.Read();}/// summary/// 辅助线程一/// /summarystatic void eowOne(AutoResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程一做完了它的事,耗时:{0}, watch.ElapsedMilliseconds/1000);mre.Set();}/// summary/// 辅助线程二/// /summarystatic void eowTwo(AutoResetEvent mre){var watch Stopwatch.StartNew();Thread.Sleep(2000);watch.Stop();Console.WriteLine(辅助线程二做完了它的事,耗时:{0}, watch.ElapsedMilliseconds / 1000);var status mre.Set();if (status){mre.Reset();}}     转载于:https://www.cnblogs.com/GreenLeaves/p/9980979.html
http://www.yutouwan.com/news/87439/

相关文章:

  • 网络公司网站建设报价滨江建设交易门户网站
  • win2012做网站个人房屋做民宿在哪个网站
  • 泉州市建设局网站公示学视频剪辑去哪里学比较好
  • 做网站的开发软件建设银行网站用户名忘了怎么办
  • 上海有哪些做网站南充房产信息网
  • ps做网站尺寸多少像素工业网站建设
  • 龙华响应式网站建设七星彩网站建设
  • 怎么做科技小制作视频网站app是什么公司
  • 有什么网站专门做美食的吗免费域名备案
  • 咋做黄页网站visio画网站开发类图
  • php做网站优点114啦建站程序
  • 云天下网站建设wordpress自定义登录框插件
  • 网站建设的专业性对搜索引擎营销的影响企业网络营销现状报告
  • 莆田人做的网站canvas做的网站
  • 微网站下载资料怎么做施工企业资质序列
  • 个人网站建设论文好的手机端网站模板下载安装
  • 做纺织都有那些好网站建团购网站
  • 在线教育网站开发方案wordpress修改网页端口
  • 免费图标下载网站什么平台可以做网站推广
  • 网站建设销售职责中国建筑集团2023招聘官网
  • 商城网站前期seo应该怎么做河北省和城乡住房建设厅网站
  • 网站页面设计风格做网站设计工资多少钱
  • 青岛网站制作公司网络用php做网站的优势
  • 移动端网站怎么制作做电力公司网站
  • 用模板快速建站网站建设基础流程图
  • 云南网站建设企业网站域名名字
  • 做网站费用联系方式电子商务网站建设费用
  • 在深圳找工作哪个网站好cp网站建设
  • 做网站空间会招攻击中国招标信息网
  • 优秀的国外设计网站哪些网站做的好处和坏处