博客
关于我
取消任务
阅读量:398 次
发布时间:2019-03-05

本文共 3591 字,大约阅读时间需要 11 分钟。

CancellationToken.None 是一个等同于默认的特殊值,表示这个方法是永远不会被取消的。

实例代码

static async Task CancelableMethodAsync(CancellationToken token){    await Task.Delay(1000, token);    throw new ArgumentException();}public static async Task IssueCancelRequestAsync(){    var cts = new CancellationTokenSource();    var task = CancelableMethodAsync(cts.Token);    // 这里,操作在正常运行。    // 发出取消请求。    cts.Cancel();    //(异步地)等待操作结束。    try    {        await task;        // 如运行到这里,说明在取消请求生效前,操作正常完成 。    }    catch (OperationCanceledException ex)    {        // 如运行到这里,说明操作在完成前被取消。        System.Console.WriteLine(ex.GetType().Name);    }    catch (Exception ex)    {        // 如运行到这里,说明在取消请求生效前,操作出错并结束。        System.Console.WriteLine(ex.GetType().Name);    }}

输出:

TaskCanceledException

1. 取消请求

public static int CancelableMethod(CancellationToken cancellationToken){    for (int i = 0; i != 100000; ++i)    {        // cancellationToken.WaitHandle.WaitOne(1000);        Thread.Sleep(1);        // 这里做一些计算工作。        if (i % 1000 == 0)            cancellationToken.ThrowIfCancellationRequested();    }    return 42;}

2. 超时后取消

public static async Task IssueTimeoutAsync(){    Stopwatch sw = Stopwatch.StartNew();    try    {        var cts = new CancellationTokenSource();        var token = cts.Token;        cts.CancelAfter(TimeSpan.FromSeconds(2));        await Task.Delay(TimeSpan.FromSeconds(4), token);    }    finally    {        System.Console.WriteLine($"{sw.ElapsedMilliseconds}ms");    }}

输出:

2004msUnhandled Exception: ... ...

只要执行代码时用到了超时,就该使用 CancellationTokenSourceCancelAfter (或者用构造函数)。虽然还有其他途径可实现这个功能,但是使用现有的取消体系是最简单也是最高效的。

3. 取消并行

public class Matrix{    public void Rotate(float degrees) { }}//只做展示public static void RotateMatrices(IEnumerable
matrices, float degrees, CancellationToken token){ Parallel.ForEach(matrices, new ParallelOptions { CancellationToken = token }, matrix => matrix.Rotate(degrees));}

4. 取消响应式代码

注入取消请求

  • 某一个层次的代码需要响应取消请求,同时它本身也要向下一层代码发出取消请求(但不会向上传递)。
public static async Task RunGetWithTimeoutAsync(){    CancellationTokenSource source = new CancellationTokenSource();    await GetWithTimeoutAsync("http://www.baidu.com", source.Token);}public static async Task
GetWithTimeoutAsync(string url, CancellationToken cancellationToken){ var client = new HttpClient(); using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cts.CancelAfter(TimeSpan.FromMilliseconds(100)); var combinedToken = cts.Token; return await client.GetAsync(url, combinedToken); }}

输出:

Unhandled Exception: Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AggregateException: One or more errors occurred. (A task was canceled.) ---> System.Threading.Tasks.TaskCanceledException ... ...

5. 与其他取消体系的互操作

有一些外部的或以前遗留下来的代码采用了非标准的取消模式。现在要用标准的CancellationToken 来控制这些代码

public static async Task RunPingAsync(){    var cts = new CancellationTokenSource();    var task = PingAsync("192.168.0.101", cts.Token);    //cts.Cancel();    await task;}public static async Task
PingAsync(string hostNameOrAddress, CancellationToken cancellationToken){ Stopwatch sw = Stopwatch.StartNew(); try { var ping = new Ping(); using (cancellationToken.Register(() => ping.SendAsyncCancel())) { return await ping.SendPingAsync(hostNameOrAddress); } } finally { System.Console.WriteLine($"{sw.ElapsedMilliseconds}ms"); }}

注意: 为了避免内存和资源的泄漏,一旦不再需要使用回调函数了,就要释放这个回调函数注册。

转载地址:http://pbozz.baihongyu.com/

你可能感兴趣的文章
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_说明操作步骤---大数据之Nifi工作笔记0028
查看>>
NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
查看>>
NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南002---大数据之Nifi工作笔记0069
查看>>
NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
查看>>
NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
查看>>
NIH发布包含10600张CT图像数据库 为AI算法测试铺路
查看>>
Nim教程【十二】
查看>>
Nim游戏
查看>>
NIO ByteBuffer实现原理
查看>>
Nio ByteBuffer组件读写指针切换原理与常用方法
查看>>
NIO Selector实现原理
查看>>