前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 多线程学习系列四之取消、超时子线程操作

C# 多线程学习系列四之取消、超时子线程操作

作者头像
郑小超.
发布2018-12-14 10:45:46
1.4K0
发布2018-12-14 10:45:46
举报
文章被收录于专栏:GreenLeavesGreenLeaves

1、简介

虽然ThreadPool、Thread能开启子线程将一些任务交给子线程去承担,但是很多时候,因为某种原因,比如子线程发生异常、或者子线程的业务逻辑不符合我们的预期,那么这个时候我们必须关闭它,而不是让它继续执行,消耗资源.让CPU不在把时间和资源花在没有意义的代码上.

2、主线程取消所有子线程执行的简单代码演示和原理分析

(1)、代码演示

代码语言:javascript
复制
        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 name="token"></param>
        static void EoworkOne(CancellationToken token)
        {
            //判断主线程是否调用了CancellationTokenSource实例的Cancel方法
            //相当于判断主线程是否传递给辅助线程一一个取消标记
            if (token.IsCancellationRequested)
            {
                //如果主线程传递给辅助线程一一个取消操作标记,执行下面的代码
                Console.WriteLine("主线程调用了Cancel方法,所以辅助线程一获取了主线程取消辅助线程一的标记,但是并不会真正的关闭当前线程");
                Console.WriteLine("辅助线程一执行return操作,自己显示的退出,那么接下去的方法都不会被执行");
                return;
            }
        }

        /// <summary>
        /// 辅助线程二
        /// </summary>
        /// <param name="token"></param>
        static void EoworkTwo(CancellationToken token)
        {
            //判断主线程是否调用了CancellationTokenSource实例的Cancel方法
            //相当于判断主线程是否传递给辅助线程一一个取消标记
            if (token.IsCancellationRequested)
            {
                //如果主线程传递给辅助线程一一个取消操作标记,执行下面的代码
                Console.WriteLine("主线程调用了Cancel方法,所以辅助线程二获取了主线程取消辅助线程二的标记,但是并不会真正的关闭当前线程");
            }
            //因为当主线程传递给辅助线程二一个取消标记,但是上面的if语句块,并没有执行return操作,所以下面的语句还是会继续执行
            Console.WriteLine("辅助线程二获得取消标记操作后,并没有执行显示的return操作,所以辅助线程二继续执行");
        }

(2)、原理分析

 第一步:创建一个CancellationTokenSource对象实例,该对象包含了所有关于取消子线程有关的所有状态

代码语言:javascript
复制
CancellationTokenSource ctsToken = new CancellationTokenSource();

 第二步:将CancellationTokenSource对象实例的CancellationToken对象实例传递给需要进行取消操作的所有子线程.并且可以通过这个CancellationToken对象实例关联到CancellationTokenSource对象实例.

代码语言:javascript
复制
ThreadPool.QueueUserWorkItem(o => EoworkOne(ctsToken.Token));
ThreadPool.QueueUserWorkItem(o => EoworkTwo(ctsToken.Token));

 第三步:当主线程调用CancellationTokenSource对象实例的Cancel方法,所有的子线程通过调用CancellationToken对象实例的IsCancellationRequested属性,该属性定时去获取初始线程(主线程)是否执行了CancellationTokenSource对象实例的Cancel方法,如果调用了,该属性为true。这时可以理解为子线程到主线程的取消信号,可以通过调用return方法来终止子线程的操作.

代码语言:javascript
复制
   //判断主线程是否调用了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.

代码语言:javascript
复制
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(o => EoworkOne(CancellationToken.None));
            Console.Read();
        }

        /// <summary>
        /// 辅助线程一
        /// </summary>
        /// <param name="token"></param>
        static void EoworkOne(CancellationToken token)
        {
            if (token.IsCancellationRequested)
            {
                //永远无法执行
            }
            Console.WriteLine("辅助线程一能被取消吗?{0}",token.CanBeCanceled?"能":"不能");
            Console.WriteLine("通过CancellationToken.None实例创建的子线程无法被取消");
        }

4、初始线程(主线程)调用给CancellationTokenSource对象实例的Cancel方法添加回调函数

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档