我玩取消令牌,我想了解这是如何工作的。我有两个异步方法(在我的例子中有两个,但理论上我可以有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已完成
您好
主要例外+取消
我希望secondAsync停止延迟并抛出OperationCancelException。 我期待这个结果:
开始
第一次通话中的例外
主要例外+取消
Main OperationCanceledException取消
我在哪里弄错了? 为什么方法SecondAsync完全执行并且不抛出异常?如果我更改SecondAsync和FirstAsync的顺序而不是Second方法停止延迟到令牌被取消并抛出异常。
答案 0 :(得分:3)
因为代码的相关部分是:
try
{
...
await secondTask;
await firstTask;
}
catch(...)
{
source.Cancel();
}
现在,当firstTask启动并抛出时,等待在第二个任务之后。在等待任务之前,异常不会在调用者中浮出水面。因此catch子句只会在secondTask完成后执行。 Cancel()发生得太晚了。
如果你想让你的firstTask中断第二个,你必须
答案 1 :(得分:0)
您的CancellationTokenSource
需要位于被调用方法可访问的范围内,并且您需要调用CancellationTokenSource.Cancel()
以取消使用该源的所有操作。
您也可以致电CancellationTokenSource.CancelAfter(TimeSpan)
以延迟取消。