一、经常使用的方式
1、首先构建一个CancellationTokenSource实例
var cts=new CancellationTokenSource();
2、取消任务
cts.Cancel();
3、再构建一个CancellationToken实例
CancellationToken token = cts.Token;
4、token.IsCancellationRequested属性
说明是否请求取消任务。如果该属性为true,只保证已请求取消。
5、使用CancellationTokenSource对象需要与Task对象进行配合使用,Task会对当前运行的状态进行控制(这个不用我们关心是如何孔控制的)。而CancellationTokenSource则是外部对Task的控制,如取消、定时取消。
定时取消:
一个任务超过了我们所设定的时间然后自动取消该任务的执行。如下代码所示
var cancelTokenSource = new CancellationTokenSource(3000);
除了构造函数,我们还可以使用另外一种方式实现定时取消,如下代码所示
cancelTokenSource.CancelAfter(3000);
运行起来效果是一样的,3秒钟定时取消。
二、取消一个异步操作的理论依据
一些.NET异步方法允许你请求终止执行。System.Threading.Tasks命名空间中有2个类是为此目的而设计的:CancellationToken和CancellationTokenSource。
1.CancellationToken对象包含一个任务是否应被取消的信息;
2.拥有CancellationToken对象的任务需要定期检查其令牌(token)状态。
如果CancellationToken对象的IsCancellationRequested属性为true,任务需停止其操作并返回。
3.CancellationToken是不可逆的,并且只能是使用一次。
也就是说,一旦IsCancellationRequested属性被设置为true,就不能更改了。
4.CancellationTokenSource的对象创建可分配给不同任务的CancellationToken对象。
任何持有CancellationTokenSource的对象都可以调用其Cancel方法,这会将CancellationToken的IsCancellationRequested属性设置为true。
注意:CancellationTokenSource和CancellationToken是协同的,实现取消操作。调用CancellationTokenSource的Cancel时,它本身并不会执行取消任务操作,而是会将CancellationToken的IsCancellationRequested属性设置为true。
三、代码演示
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
MyClass mc = new MyClass();
//这个异步任务 和 下面的代码并行运行(同一时间内,既运行这个任务,又运行下面代码)
Task t = mc.RunAsync( token );
Thread.Sleep(3000); // Wait 3 seconds.
//请求取消任务(会将CancellationToken的IsCancellationRequested属性设置为true)
cts.Cancel(); //cancel the operation.
//等待任务t完成,才继续执行后续代码
t.Wait();
Console.WriteLine( "Was Cancelled: {0}", token.IsCancellationRequested );
Console.Read();
}
}
class MyClass
{
public async Task RunAsync( CancellationToken ct )
{
//定期检查其令牌(token)状态
if ( ct.IsCancellationRequested )
return;
//执行方法(当接收到CycleMethod方法返回的时候,该任务完成)
await Task.Run( () => CycleMethod( ct ), ct );
}
void CycleMethod( CancellationToken ct )
{
Console.WriteLine( "Starting CycleMethod" );
const int max = 5;
for ( int i=0; i < max; i++ )
{
//定期检查其令牌(token)状态,如果为true--直接返回
if ( ct.IsCancellationRequested ) // Monitor the CancellationToken.
return;
Thread.Sleep( 1000 );
Console.WriteLine( " {0} of {1} iterations completed", i + 1, max );
}
}
}
允许结果显示: