异步方法中取消异步操作

1、在异步方法中取消异步操作,第一步必须声明CancellationToken和CancellationTokenSource两个类对象,并将两个类通过 CancellationTokenSource 对象的token属性关联;

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token; //将CancellationTokenSource cts对象与CancellationToken token对象关联

2 、通过调用CancellationTokenSource的Cancel()方法使异步方法中或异步方法中的await表达式中的CancellationToken的IsCancellationRequested属性为True,从而终止异步方法或异步方法中的await表达式的执行。

 public async Task RunAsync(CancellationToken ct)//异步方法中多了CancellationToken类类型的形参
        {
            if(ct.IsCancellationRequested)
            {
                return;
            }
            await Task.Run(() => CycleMethod(ct), ct);//public static Task Run(Action action, CancellationToken cancellationToken); Action是一个无参数无返回值的委托,为什么CycleMethod方法明明是一个有参数的委托
        }                                             //确能够在Run中使用

3、异步方法或异步方法中的await表达式都包含一个CancellationToken类型的形参,只要程序调用CancellationTokenSource类的Cancel()方法,异步方法和await表达式中的方法检测到CancellationToken的IsCancellationRequested属性为True都会终止。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _CancellationToken
{
    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken token = cts.Token;        //将CancellationTokenSource cts对象与CancellationToken token对象关联
            MyClass mc = new MyClass();
            Task t = mc.RunAsync(token);
            Thread.Sleep(3000);//等待3秒
            cts.Cancel();
            t.Wait();
            Console.WriteLine("Was Cancelled: {0}",token.IsCancellationRequested);
            Console.ReadKey();
        }
    }
    class MyClass
    {
        public async Task RunAsync(CancellationToken ct)//异步方法中多了CancellationToken类类型的形参
        {
            if(ct.IsCancellationRequested)
            {
                return;
            }
            await Task.Run(() => CycleMethod(ct), ct);//public static Task Run(Action action, CancellationToken cancellationToken); Action是一个无参数无返回值的委托,为什么CycleMethod方法明明是一个有参数的委托
        }                                             //确能够在Run中使用

        void  CycleMethod(CancellationToken ct)
        {
            Console.WriteLine("Starting CycleMethod");
            const int Max = 5;
            for (int i = 0; i < Max; i++)
			{
                if (ct.IsCancellationRequested)
                {
                    return;
                }
                Thread.Sleep(1000);
                Console.WriteLine("   {0} of {1} iterations completed",i+1,Max);
			}
        }
    }
}

猜你喜欢

转载自blog.csdn.net/ABC13222880223/article/details/85232661