我正在使用取消令牌,并希望了解其工作原理。我有两个异步方法(在我的示例中是两个,但理论上我可以有 100 个)。
如果其中一个方法抛出异常,我想取消所有异步方法的工作。
我的想法是,在调用所有方法的异常中取消令牌。当令牌被取消时,我期望其他方法停止工作,但实际上并没有发生。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace CancelationTest
{
class Program
{
static void Main(string[] args)
{
new Test();
Console.ReadKey();
}
}
public class Test
{
public Test()
{
Task.Run(() => MainAsync());
}
public static async Task MainAsync()
{
var cancellationTokenSource = new CancellationTokenSource();
try
{
var firstTask = FirstAsync(cancellationTokenSource.Token);
var secondTask = SecondAsync(cancellationTokenSource.Token);
Thread.Sleep(50);
Console.WriteLine("Begin");
await secondTask;
Console.WriteLine("hello");
await firstTask;
Console.WriteLine("world");
Console.ReadKey();
}
catch (OperationCanceledException e)
{
Console.WriteLine("Main OperationCanceledException cancel");
}
catch (Exception e)
{
Console.WriteLine("Main Exception + Cancel");
cancellationTokenSource.Cancel();
}
}
public static async Task FirstAsync(CancellationToken c)
{
c.ThrowIfCancellationRequested();
await Task.Delay(1000, c);
Console.WriteLine("Exception in first call");
throw new NotImplementedException("Exception in first call");
}
public static async Task SecondAsync(CancellationToken c)
{
c.ThrowIfCancellationRequested();
await Task.Delay(15000, c);
Console.WriteLine("SecondAsync is finished");
}
}
}
第二种方法即使第一种方法抛出异常也会完成工作并延迟任务15秒。
结果是什么:
开始 第一次调用中的异常 SecondAsync已完成 你好 Main Exception + Cancel
我期望secondAsync停止延迟并抛出OperationCanceledException。
我期望这个结果:
开始 第一次调用中的异常 主要异常+取消 主要OperationCanceledException取消
我在哪里犯了错误? 为什么SecondAsync方法完全执行而不抛出异常?如果我改变SecondAsync和FirstAsync的顺序,那么当标记被取消时,第二种方法将停止延迟并抛出异常。
CancellationToken
给Task.Delay
时,如果令牌被触发,延迟是否应该被取消? - user4003407ThrowIfCancellationRequested
仅仅检查是否已经请求了取消操作,如果是,则抛出异常,否则不执行任何操作。它不会在稍后被取消时抛出异常。 - Fabjan