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);
}
}
}
}
程序二:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Process
{
public partial class Form1 : Form
{
CancellationTokenSource _cancellationTokenSource;
CancellationToken _cancellationToken;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private async void btnprocess_Click(object sender, EventArgs e)
{
btnprocess.Enabled = false;
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = new CancellationToken();
_cancellationToken = _cancellationTokenSource.Token; //使_cancellationTokenSource对象和_cancellationToken对象关联
int completedPercent = 0;
for (int i = 0; i < 10; i++)
{
if (_cancellationToken.IsCancellationRequested)
{
break;
}
try //异步方法中的await表达式异常处理
{
await Task.Delay(500, _cancellationToken); //await Task.Delay(50); 效果一样
//Thread.Sleep(1000);
completedPercent = (i+1)*10;
}
catch (TaskCanceledException ex)
{
completedPercent = i * 10;
}
progressBar1.Value = (i+1) * 10; //设置进度条的值
this.textBox1.Text = progressBar1.Value.ToString(); //Text文档中显示进度条的进度值
}
string message = _cancellationToken.IsCancellationRequested ? string.Format("Process was canceled at {0}%", completedPercent) : "Process completed normally";
MessageBox.Show(message,"Completion Status");
progressBar1.Value = 0;
btnprocess.Enabled = true;
btnCancel.Enabled = true;
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (!btnprocess.Enabled)
{
btnCancel.Enabled = false;
_cancellationTokenSource.Cancel(); //调用CancellationTokenSource中的Cancel方法使CancellationToken中的IsCancellationRequested为True ,设备中的急停响应按钮
this.textBox1.Text = "";
}
}
}
}