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

你可能感兴趣的文章
MYSQL CONCAT函数
查看>>
multiprocessing.Pool:map_async 和 imap 有什么区别?
查看>>
MySQL Connector/Net 句柄泄露
查看>>
multiprocessor(中)
查看>>
mysql CPU使用率过高的一次处理经历
查看>>
Multisim中555定时器使用技巧
查看>>
MySQL CRUD 数据表基础操作实战
查看>>
multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
查看>>
mysql csv import meets charset
查看>>
multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
查看>>
MySQL DBA 数据库优化策略
查看>>
multi_index_container
查看>>
MySQL DBA 进阶知识详解
查看>>
Mura CMS processAsyncObject SQL注入漏洞复现(CVE-2024-32640)
查看>>
Mysql DBA 高级运维学习之路-DQL语句之select知识讲解
查看>>
mysql deadlock found when trying to get lock暴力解决
查看>>
MuseTalk如何生成高质量视频(使用技巧)
查看>>
mutiplemap 总结
查看>>
MySQL DELETE 表别名问题
查看>>
MySQL Error Handling in Stored Procedures---转载
查看>>