C#多线程编程笔记(3.2)-CancellationToken取消异步操作

近来在学习Eugene Agafonov编写的《C#多线程编程实战》(译),做些笔记也顺便分享一下^-^

using System;
using System.Threading;

namespace 线程池中取消异步操作
{
    class Program
    {
        static void Main(string[] args)
        {
            using(var cts=new CancellationTokenSource())
            {
                CancellationToken token = cts.Token;
                ThreadPool.QueueUserWorkItem(_ => AsyncOperation1(token));
                Thread.Sleep(TimeSpan.FromSeconds(2));
                cts.Cancel();
            }

            using (var cts = new CancellationTokenSource())
            {
                CancellationToken token = cts.Token;
                ThreadPool.QueueUserWorkItem(_ => AsyncOperation2(token));
                Thread.Sleep(TimeSpan.FromSeconds(2));
                cts.Cancel();

            }

            using (var cts = new CancellationTokenSource())
            {
                CancellationToken token = cts.Token;
                ThreadPool.QueueUserWorkItem(_ => AsyncOperation3(token));
                Thread.Sleep(TimeSpan.FromSeconds(2));
                cts.Cancel();
            }

            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.ReadKey();
        }

        static void AsyncOperation1(CancellationToken token)
        {
            Console.WriteLine("Starting the first task");
            for (int i = 0; i < 5; i++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("The first task has been canceled.");
                    return;
                }
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            Console.WriteLine("The first task has completed succesfully");
        }

        static void AsyncOperation2(CancellationToken token)
        {
            try
            {
                Console.WriteLine("Starting the second task");
                for (int i = 0; i < 5; i++)
                {
                    token.ThrowIfCancellationRequested();
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
                Console.WriteLine("The second task has completed successfully");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("The second task has been canceled.");
            }
        }

        private static void AsyncOperation3(CancellationToken token)
        {
            bool cancellationFlag = false;
            token.Register(() => cancellationFlag = true);
            Console.WriteLine("Starting the third task");
            for (int i = 0; i < 5; i++)
            {
                if (cancellationFlag)
                {
                    Console.WriteLine("The third task has been canceled.");
                    return;
                }
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            Console.WriteLine("The third task has completed successfully");
        }
    }
}

这里引入了两个类CancellationToken和CancellationTokenSource,是实现异步操作的取消操作的事实标准。

程序里一共使用了三种方式来实现取消过程:1、通过轮询来检查CancellationToken.IsCancellationRequested属性,如果该属性为true,则说明操作需要被取消,我们必须放弃该操作。

2、抛出一个OperationCanceledException异常,这允许在操作之外控制取消过程,即需要取消操作时,通过操作之外的代码来处理。

3、注册一个回调函数,当操作被取消时,在线程池将调用该回调函数,这允许链式传递一个取消逻辑到另一个异步操作中。

你可能感兴趣的:(C#-多线程,C#多线程编程笔记,C#,线程池,异步操作)