c# CancellationTokenSource用于线程循环中断

发现个好玩的东东,CancellationTokenSource,可以用来对线程的中断进行控制,原先一直使用 static bool run 来控制的,现在改成这种的也挺不错,并且有之外的收获

Demo:

        public void FooRun()
        {
            Console.WriteLine("Create a new thread in ThreadPool:...");
            // create cancellationTokenSource, which decide when to cancel(abort) thread
            CancellationTokenSource cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(o => LoopFoo(cts.Token, 1000)); // delegate without parameter (WaitCall)
            Thread.Sleep(180);
            cts.Cancel();
            Console.WriteLine("FooRun Done...");
        }

        public void LoopFoo(CancellationToken token, int countTo)
        {
            int i = 0;
            while (i++ < countTo)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Is canceled...");
                    break;
                }
                // do something not care    
                Console.WriteLine(i);
                Thread.Sleep(10);
            }
            Console.WriteLine("LoopFoo Done...");
        }

 

可以看到,在望线程池丢一个Item的时候传了个 CancellationTokenSource 对象,它可以在线程的内部作为一个开关量使用,在主线程就可以在任意时间cancel掉它,然后让线程终止。

当然,如果只能这样,那就和static bool没有区别了,之所以我觉得有趣,是因为还活得了一个调用回调函数的机会

            // create cancellationTokenSource, which decide when to cancel(abort) thread
            CancellationTokenSource cts = new CancellationTokenSource();
           cts.Token.Register(() => Console.WriteLine("CancellationToken register callback function invoked..."));
            ThreadPool.QueueUserWorkItem(o => LoopFoo(cts.Token, 1000)); // delegate without parameter (WaitCall)
            Thread.Sleep(180);
            cts.Cancel();

可以注册多个Action<>,那就调用多个了。这点倒是很有意思,给你了更多的控制线程的方式。

还有一种link的方式创建TokenSource,这种方式使得如果关联的TokenSource,cancel了,那么将导致这个TokenSource也会cancel            CancellationTokenSource one = new CancellationTokenSource();


            one.Token.Register(() => Console.WriteLine("One register function invoked..."));
            //create another new cancellationTokenSource
            CancellationTokenSource two = new CancellationTokenSource();
            two.Token.Register(() => Console.WriteLine("Two register function invoked..."));
            //create a linked cancelationTokenSource
            CancellationTokenSource three = CancellationTokenSource.CreateLinkedTokenSource(one.Token, two.Token);
            three.Token.Register(() => Console.WriteLine("Three register function invoked..."));
            Console.WriteLine("One's IsCancellationRequested: {0} \nTwo's IsCancellationRequested: {1} \nThree'sIsCancellationRequested: {2}",
                one.IsCancellationRequested, two.IsCancellationRequested, three.IsCancellationRequested);
            two.Cancel();
            Console.WriteLine("One's IsCancellationRequested: {0} \nTwo's IsCancellationRequested: {1} \nThree'sIsCancellationRequested: {2}",
                one.IsCancellationRequested, two.IsCancellationRequested, three.IsCancellationRequested);
            one.Cancel();
            Console.WriteLine("One's IsCancellationRequested: {0} \nTwo's IsCancellationRequested: {1} \nThree'sIsCancellationRequested: {2}",
                one.IsCancellationRequested, two.IsCancellationRequested, three.IsCancellationRequested);

虽然暂时没有想到用在哪里,但是感觉还是很有用处的。

可以看到,CancellationToken 是真正起作用的关键点,CancellationTokenSource是对它的一个包装,在内部,定义了CancellationToken对象, 它是一个结构体,重载了!= ==操作符。如果想在最开始的Demo中不让线程由CancellationToken控制而退出,那可以在传参 CancellationToken.None

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值