1. 程式人生 > >非同步方法中取消非同步操作

非同步方法中取消非同步操作

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);
			}
        }
    }
}