第26章 计算限制的异步操作(5)

本文介绍如何使用CancellationToken取消Task,探讨了通过ThrowIfCancellationRequested方法实现操作取消的过程及异常处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26.5.2 取消任务

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            Task<int> t = new Task<int>(n => Sum(cts.Token,100),cts.Token);//区别于线程池,两个参数
            t.Start();
            cts.Cancel();
            try
            {
                Console.WriteLine("The sum is:" + t.Result);
            }
            catch (AggregateException e)
            {
                e.Handle(ex => ex is OperationCanceledException);
                Console.WriteLine("The Task was canceled...");
            }
        }

        static int Sum(CancellationToken ct, int num)
        {
            Thread.Sleep(100);

            ct.ThrowIfCancellationRequested();

            if (num == 0)
                return 0;
            else
                return num + Sum(ct, num - 1);
        }
    }
}
The Task was canceled...
Press any key to continue . . .
在计算限制操作的循环中,我们通过调用CancellationToken的ThrowIfCancellationRequested方法定时检查操作是否已经取消。这个方法和Cancellation的IsCancelationRequested属性是相似的。然而,如果CancellationTokenSource已经取消,ThrowIfCancellationRequested会抛出一个OperationCanceledException。之所以选择抛出一个异常,是因为有别于由ThreadPool会抛出一个的QueueUserWorkItem方法所初始化的工作项(work item),任务有表示已完成的方法,任务甚至还能返回一个值。所以,需要采取一种方法将已完成的任务和出错的任务区分开。而让任务抛出一个异常,就可以知道任务没有一直运行到结束。

创建一个Task时,可以将一个CancellationToken传给Task的构造器,从而将这个CancellationToken和该Task关联起来。如果CancellationToken在Task调度前取消,Task会被取消,永远都不会执行。但是,如果Task已经调度(通过调用Start方法),那么Task为了允许它的操作在执行期间取消,Task的代码就必须显式支持取消。遗憾的是,虽然Task对象关联了一个CancellationToken,但却没有办法访问它。因此,必须通过某种方式,在Task的代码本身中获得用于创建Task对象的同一个CancellationToken。为了写这样的代码,最简单的办法就是使用一个Lambda表达式,并将CancellationToken作为一个闭包变量"传递"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值