C#多线程之取消架构介绍

作者:Ruby_Lu 时间:2022-03-06 22:14:42 

.NET 4.5 中包含取消架构,允许以标准方式取消长时间运行的任务。每个阻塞调用都应支持这种机制。但目前,并不是所有阻塞调用都实现了这个新技术。已经实现了这种机制的技术有任务(https://www.jb51.net/article/244285.htm),并发集合类(https://www.jb51.net/article/244141.htm),并行LINQ(https://www.jb51.net/article/244216.htm)和几种同步机制。
取消架构基于协作行为,它不是强制的。长时间运行的任务会检查它是否被取消,并返回控制权。
支持取消的方法接受一个CancellationToken参数。这个类定义了IsCancellationRequested属性,其中长时间运行的操作可以检查它是否应终止。使用Register()方法注册一个将在取消此 System.Threading.CancellationToken 时调用的委托。它在调用Cancel()方法取消操作时调用。

1.Parallel.For()方法的取消

Parallel类提供了For()方法的重载版本,在重载版本中,可以传递ParallelOptions类型的参数。使用ParallelOptions类型,可以传递一个CancellationToken参数。CancellationToken参数通过创建CancellationTokenSource来生成。由于CancellationTokenSource实现了ICancelableOperation接口,因此可以用CancellationToken注册,并允许使用Cancle(),CancleAfter()等方法取消操作。
示例:

static void CancelParallelFor()
       {
           var cts = new CancellationTokenSource();
           cts.Token.Register( ()=> Console.WriteLine("token canceled!"));

cts.CancelAfter(1000);

try
           {
               ParallelLoopResult plr =
                   Parallel.For(0, 100, new ParallelOptions { CancellationToken = cts.Token },
                   x => {
                       Console.WriteLine("loop {0} started", x);
                       Thread.Sleep(1000);
                       Console.WriteLine("loop {0} fininshed!", x);
                   });
           }
           catch (OperationCanceledException ex)
           {
               Console.WriteLine(ex.Message);

}
       }

输出:

C#多线程之取消架构介绍

在For循环的实现代码中,Parallel类验证CancellationToken的结果,并取消操作。一旦取消操作,For()方法就抛出一个OperationCanceledException类型的异常。
由输出可看出,当取消操作时,已启动的操作允许完成,因为取消操作总是以协作方式进行,以避免在取消迭代操作的中间泄露资源。

2.任务的取消

任务的取消类似Parallel.For()方法的取消。首先,创建一个CancellationTokenSource。如果只需要一个取消标记,可以访问Task.Factory.CancellationToken,以使用默认的取消标记。任务通过TaskFactory对象接受取消标记。在构造函数中,把取消标记赋予TaskFactory。这个取消标记又任务用于检查CancellationToken的IsCancellationRequested属性,以确定是否请求了取消。
示例:

static void CancelTask()
       {
           var cts = new CancellationTokenSource();

cts.Token.Register(() => Console.WriteLine("task cancelled!"));

cts.CancelAfter(2000);

try
           {
               Task t = Task.Run(() =>
               {
                   CancellationToken token = cts.Token;
                   Console.WriteLine("task stared!");
                   for (int i = 0; i < 20; i++)
                   {
                       Thread.Sleep(500);
                       if (cts.IsCancellationRequested)
                       {
                           Console.WriteLine("cancelled!");
                           token.ThrowIfCancellationRequested();//抛出异常
                           break;
                       }
                       Console.WriteLine("in loop!");
                   }
               }, cts.Token);
               t.Wait();
           }
           catch (AggregateException ex)
           {
               Console.WriteLine("exception:{0},{1}",ex.GetType().Name,ex.Message);
               foreach (var innerEx in ex.InnerExceptions)
               {
                   Console.WriteLine("exception:{0},{1}", ex.InnerException.GetType().Name, ex.InnerException.Message);
               }
           }
       }

输出:

C#多线程之取消架构介绍

来源:https://www.cnblogs.com/afei-24/p/6917767.html

标签:C#,多线程,取消,架构
0
投稿

猜你喜欢

  • DrawerLayout的简单使用及侧滑菜单实现详解

    2023-04-27 04:10:59
  • SpringMVC中事务是否可以加在Controller层的问题

    2021-12-09 01:20:15
  • WPF+Canvas实现平滑笔迹的示例代码

    2021-10-06 06:35:13
  • Android基于讯飞语音SDK实现语音识别

    2023-09-26 23:39:05
  • Spring中Bean的生命周期使用解析

    2021-09-06 23:06:54
  • 轻量级声明式的Http库——Feign的独立使用

    2022-06-05 04:36:19
  • Android优化之电量优化的实现

    2023-08-20 07:57:25
  • Android使用RecyclerView实现水平滚动控件

    2021-09-10 20:17:54
  • Android编程中EditText限制文字输入的方法

    2023-07-19 07:30:48
  • SpringBoot整合RedisTemplate实现缓存信息监控的步骤

    2023-10-14 10:17:13
  • C# 注册表 操作实现代码

    2023-07-02 21:53:22
  • 消息队列-kafka消费异常问题

    2023-02-02 07:08:05
  • Java实现合并多个PDF的示例代码

    2023-04-29 13:25:32
  • C#特性 扩展方法

    2023-01-15 03:45:15
  • java substring 截取字符串的方法

    2023-02-12 17:21:19
  • Android自定义定时闹钟开发

    2023-07-07 00:18:01
  • 用Java连接sqlserver数据库时候几个jar包的区别分析

    2021-11-07 02:18:01
  • Spring Boot 整合JPA 数据模型关联使用操作(一对一、一对多、多对多)

    2022-11-18 23:14:29
  • java ssm框架实现分页功能的示例代码(oracle)

    2021-10-31 01:14:40
  • 如何更改Dialog的标题与按钮颜色详解

    2023-06-01 23:54:54
  • asp之家 软件编程 m.aspxhome.com