在async/await模式下,一些.NET的异步方法是允许取消执行的。System.Theading.Tasks命名空间(更正:此处应该是System.Theading命名空间)中有两个类是为此目的而设计的:CancellationToken和CancellationTokenSource。
- CancellationToken对象包含一个任务是否应被取消的信息。
- 拥有CancellationToken对象的任务需要定期检查其令牌(token)状态。如果CancellationToken对象的IsCancellationRequested属性为true,任务需停止其操作并返回。
- CancellationToken是不可逆的,并且只能使用一次。
- CancellationTokenSource对象创建可分配给不同任务的CancellationToken对象。任何持有CancellationTokenSource对象都可以调用其Cancel方法,这将使CancellationToken的IsCancellationRequested属性被设置为true。
下面的代码展示了如何使用CancellationTokenSource和CancellationToken来实现取消操作。请注意,该过程是协同的。即调用CancellationTokenSource的Cancel时,它本身并不会执行取消操作,而是会将CancellationToken的IsCancellationReqested属性设置为true。包含CancellationToken的代码负责检查该属性,并判断是否需要停止执行并返回。
class Program
{
static void Main()
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = new CancellationToken();
MyClass mc = new MyClass();
Task t = mc.RunAsync(token);
Thread.Sleep(3000);
cts.Cancel();
t.Wait();
Console.WriteLine("Was Cancellationed: {0}",token.IsCancellationRequested);
}
}
class MyClass
{
public async Task RunAsync(CancellationToken ct)
{
if (ct.IsCancellationRequested) return;
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++)
{
if (ct.IsCancellationRequested) return; // 监控CancellationToken
Thread.Sleep(1000);
Console.WriteLine(" {0} of {1} iterations completed", i + 1, max);
}
}
}
代码中循环设置为5次,但3秒后被取消,产生的结果如下:
Starting CycleMethod
1 of 5 iterations completed
2 of 5 iterations completed
3 of 5 iterations completed
Was Cancellationed: True
网友评论