欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

线程安全使用(五)

程序员文章站 2022-05-13 21:46:31
CancellationToken的多种应用 这是线程安全的最后一篇了,主要介绍CancellationToken的多种应用。 1,ThreadPool直接启动线程,传递CancellationToken。 2,Task启动线程,传递CancellationToken。Task传递方式分为两种,一种 ......
 CancellationToken的多种应用

这是线程安全的最后一篇了,主要介绍CancellationToken的多种应用。

1,ThreadPool直接启动线程,传递CancellationToken。

2,Task启动线程,传递CancellationToken。Task传递方式分为两种,一种通过Task的参数进行传递,另一种通过向线程内传递对象的方式传递CancellationToken。

3,CancellationToken的回调函数应用。

话不多说,请看代码。

  class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("当前线程{0},当前状态{1}", Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.ThreadState);
            //使用线程池创建线程,然后取消线程
            CancelWithThreadPoolMiniSnippet();
        }
        static CancellationTokenSource cts = new CancellationTokenSource();
        static CancellationToken token = cts.Token;
        static void CancelWithThreadPoolMiniSnippet()
        {
            Console.WriteLine("当前线程{0},当前状态{1}", Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.ThreadState);

            #region 使用QueueUserWorkItem的构造函数,传递cts.Token,但我不喜欢这个模式 跟踪不了状态
            //ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), ctn);
            #endregion

            #region 使用传递参数的模式 传递CancellationToken,这里的cts.Token是作为Action的参数传递的
            //var action = new Action<object>(DoSomeWork);
            //Task t = new Task(action, ctn);
            //t.Start();
            //Console.WriteLine("开始,当前线程{0},当前状态{1}", t.GetHashCode(), t.Status);
            #endregion

            #region 使用Task的构造函数,传递cts.Token,但CancellationTokenSource要弄成全局变量,否则方法找不到,就取消不了。
            //Task t = new Task(Work, cts.Token);
            //t.Start();
            #endregion

            #region 注册回调函数,当CancellationTokenSource.Cancel()执行后,调用回调函数 
            token.Register(CallBack, true);  //注册回调函数
            Task t = new Task(Work);
            t.Start();
            #endregion

            Thread.SpinWait(5000000);
            
            cts.Cancel();
            Console.WriteLine("结束,当前线程{0},当前状态{1}", t.GetHashCode(), t.Status);
            Console.Read();
        }

       
        static void DoSomeWork(object obj)
        {
            CancellationToken token = (CancellationToken)obj;
            for (int i = 0; i < 100000; i++)
            {
                Console.WriteLine(i);
                // Simulating work.
                //Thread.SpinWait(5000000);

                if (token.IsCancellationRequested)
                {
                   
                    break;
                }
            }
        }


        static void Work()
        {
           
            for (int i = 0; i < 100000; i++)
            {
                Console.WriteLine(i);
                if (token.IsCancellationRequested)
                {

                    break;
                }
            }
        }

        static void CallBack()
        {
            
            Console.WriteLine("I'm call back!"   );
        }
    }

代码内执行结果如下,该结果为CancellationToken的回调函数应用:

线程安全使用(五)

到此NET Framework4.0里的线程安全就都讲完了。。。。。。。

虽然第一篇文章是2013年,虽然历时近五年,但请相信我,代码早在五年前就已经写完啦。只是我一直一直一直没配文字发出来。。。。。。

不过,也可能是最近写文字的能力有所提升,所以就完成了四和五。

不然这线程安全的文章可能还要拖。。。。。。。。哈哈

 后记

在NET Framework4.6里,微软提供了async和await语法,也是有关线程安全,我将会在新的语法相关文章里讲解async和await的用法。