• 线程池-实现一个取消选项


     三种方式

    1. 通过使用轮循操作来检查IsCancellationRequested是否为true,是则需要取消当前操作过程(直接使用return)
    2. 通过抛出一个OperationCanceledException异常来终止操作(操作之外的代码控制取消过程)
    3. 注册一个回调函数(操作取消时,线程池将调用该函数)
            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));
            }
    
            static void AsyncOperation1(CancellationToken token)
            {
                Console.WriteLine("Starting the first task");
                
                //使用轮循操作来检查IsCancellationRequested是否为true,是则需要取消当前操作过程
                for (int i = 0; i < 5; i++)
                {
                    if (token.IsCancellationRequested)//获取是否已请求取消此标记。
                    {
                        Console.WriteLine("The first task has been canceled.");
                        return;//返回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();//如果已请求取消此标记,则引发 System.OperationCanceledException。  
                        Thread.Sleep(TimeSpan.FromSeconds(1));
                    }
                    Console.WriteLine("The second task has completed succesfully");
                }
                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 succesfully");
            }

    工作原理:

    本节中介绍了CancellationTokenSource和CancellationToken两个新类。他们在.NET4.0被引入,目前是实现异步操作的取消操作的事实标准。由于线程池已经存在了很长时间,并没有特殊的API来实现取消标记功能,但是仍然可以对线程池使用上述API。

    在本程序中使用了三种方式来实现取消过程。第一个是轮询来检查CancellationToken.IsCancellationRequested属性。如果该属性为true,则说明操作需要被取消,我们必须放弃该操作。

    第二种方式是跑出一个OperationCanceledException异常。这允许在操作之外控制取消过程,即需要取消操作时,通过操作之外的代码来处理。

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

  • 相关阅读:
    unicode字符集
    534,rgba()和opacity的透明效果有什么不同?
    1004,js中的fliter
    1003,js array map()方法
    JavaScript 数据类型和数据结构
    JavaScript实现浮点数运算问题
    Chrome浏览器不能正确加载更新后JavaScript和Css文件原因及解决方法
    MySQL安装版与压缩版安装方法
    VUE列表渲染 FOR-IN和FOR-OF的区别
    for、for-in、for-of、forEach的区别
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12446691.html
Copyright © 2020-2023  润新知