博客
关于我
取消任务
阅读量: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/

你可能感兴趣的文章
Netty基础—7.Netty实现消息推送服务一
查看>>
Netty基础—7.Netty实现消息推送服务二
查看>>
Netty基础—8.Netty实现私有协议栈一
查看>>
Netty基础—8.Netty实现私有协议栈二
查看>>
Netty多线程 和 Redis6 多线程对比
查看>>
Netty学习总结(1)——Netty入门介绍
查看>>
Netty学习总结(2)——Netty的高性能架构之道
查看>>
Netty学习总结(3)——Netty百万级推送服务
查看>>
Netty学习总结(4)——图解Netty之Pipeline、channel、Context之间的数据流向
查看>>
Netty学习总结(5)——Netty之TCP粘包/拆包问题的解决之道
查看>>
Netty学习总结(6)——Netty使用注意事项
查看>>
Netty实现Http服务器
查看>>
Netty客户端断线重连实现及问题思考
查看>>
Netty工作笔记0001---Netty介绍
查看>>
Netty工作笔记0002---Netty的应用场景
查看>>
Netty工作笔记0003---IO模型-BIO-Java原生IO
查看>>
Netty工作笔记0004---BIO简介,介绍说明
查看>>
Netty工作笔记0005---NIO介绍说明
查看>>
Netty工作笔记0006---NIO的Buffer说明
查看>>
Netty工作笔记0007---NIO的三大核心组件关系
查看>>