Explore the cancellation Task

We all know that Task.Runthe method can be passed a CancellationToken, for cancellation. But how many people really go to find out about when to call CancellationSource.Canceltime method, Taskwhether it was canceled


We do an experiment

        public static async void Foo()
        {
            var source = new CancellationTokenSource();

            Task.Run(() =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Console.WriteLine("task 运行结束");
            }, source.Token);
            await Task.Delay(TimeSpan.FromSeconds(3));
            source.Cancel();
            Console.WriteLine("取消任务");
        }

Create the above program that allows a Task output "task to run over" after running five seconds, but were canceled after 3 seconds.
Here Insert Picture Description

Surprisingly, even the successful implementation of the task is completed.

To further confirm the results, we add a follow-up mission, before the end of the state to view the next task

        public static async void Foo()
        {
            var source = new CancellationTokenSource();

            Task.Run(() =>
            {
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Console.WriteLine("task 运行结束");
            }, source.Token).ContinueWith(task => Console.WriteLine(task.Status));
            await Task.Delay(TimeSpan.FromSeconds(3));
            source.Cancel();
            Console.WriteLine("取消任务");
        }

Here Insert Picture Description
As a result RanToCompletioninstead Canceled, indicating that no task is canceled

If you do not cancel before we wait for three seconds, and add tasks to start running log

        public static async void Foo()
        {
            var source = new CancellationTokenSource();

            Task.Run(() =>
            {
                Console.WriteLine("task 运行开始");
                Thread.Sleep(TimeSpan.FromSeconds(5));
                Console.WriteLine("task 运行结束");
            }, source.Token).ContinueWith(task => Console.WriteLine(task.Status));
            source.Cancel();
            Console.WriteLine("取消任务");
        }

(…/media/1548577856869.png)]Here Insert Picture Description

Tasks are normally canceled

the reason

In fact, when Task.Runthe real task begins execution, calling CancellationSource.Cancelthe method does not cancel the task, or the end of the calling thread. Method Invocation still be carried out smoothly.

So with CancellationTokenmethod overloading what use is it?

1, as shown in the third example, the task before the start of operation, the call Cancelcan be directly cancel the task, avoid excessive consumption of a thread

2, when the corresponding token, in the execution thrown body OperationCanceledException, (i.e. calls CancellationToken.ThrowIfCancellationRequested()) which can be captured, and the task state is set toCanceled

        public static async void Foo()
        {
            var source = new CancellationTokenSource();

            Task.Run(() =>
            {
                Console.WriteLine("task 运行开始");
                Thread.Sleep(TimeSpan.FromSeconds(5));
                source.Token.ThrowIfCancellationRequested();
                Console.WriteLine("task 运行结束");
            },source.Token).ContinueWith(task => Console.WriteLine(task.Status));
            await Task.Delay(TimeSpan.FromSeconds(3));
            source.Cancel();
            Console.WriteLine("取消任务");
        }

Here Insert Picture Description

And without the use of this overload, the task will be terminated due to an uncaught exception, not canceled

        public static async void Foo()
        {
            var source = new CancellationTokenSource();

            Task.Run(() =>
            {
                Console.WriteLine("task 运行开始");
                Thread.Sleep(TimeSpan.FromSeconds(5));
                source.Token.ThrowIfCancellationRequested();
                Console.WriteLine("task 运行结束");
            }).ContinueWith(task => Console.WriteLine(task.Status));
            await Task.Delay(TimeSpan.FromSeconds(3));
            source.Cancel();
            Console.WriteLine("取消任务");
        }

Here Insert Picture Description
So we Task.Runadd CancellationTokenstill need the manual to determine whether to cancel the token in the method of execution

Reference links:


This article will be updated frequently, please read personal blog Original: https://xinyuehtx.github.io/ , in order to avoid misleading the old error of knowledge, and a better reading experience.

Creative Commons License This work is Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License Agreement for licensing. Welcome to reprint, use, repost, but be sure to keep the article signed by Huang Tengxiao (containing links: https://xinyuehtx.github.io/ ), shall not be used for commercial purposes, be sure to publish the same work based on the paper license modification. If you have any questions, please contact me .

Published 54 original articles · won praise 0 · Views 2442

Guess you like

Origin blog.csdn.net/htxhtx123/article/details/104192265