C# CancellationToken未取消所有任务

C# CancellationToken未取消所有任务,c#,.net-core,C#,.net Core,NET中的TPL新手。试图了解CancellationToken以及如何通知他们取消正在执行的任务。下面的代码只传输一个被取消的任务,其中相同的令牌被传递给两个任务。我的假设是,如果超时发生在第一个任务上,并且它执行ctx.Cancel()我需要一些帮助来理解为什么我只看到一个异常,而这两个任务都应该取消。我遗漏了什么?如何确保两个任务都已取消且不占用内存资源 static void Main(string[] args) { Console.WriteLine(

NET中的TPL新手。试图了解
CancellationToken
以及如何通知他们取消正在执行的任务。下面的代码只传输一个被取消的任务,其中相同的令牌被传递给两个任务。我的假设是,如果超时发生在第一个任务上,并且它执行
ctx.Cancel()
我需要一些帮助来理解为什么我只看到一个异常,而这两个任务都应该取消。我遗漏了什么?如何确保两个任务都已取消且不占用内存资源

    static void Main(string[] args)
    {
        Console.WriteLine("Starting application");
        var ctx = new CancellationTokenSource();
        var token = ctx.Token;
        try
        {
            var task1 = new Program().Run("task1", token);
            var task2 = new Program().Run("task2", token);

            if (!task1.Wait(1000)) 
                ctx.Cancel();

            task2.Wait();
        }
        catch (AggregateException ex)
        {
            Console.WriteLine("Aggregate Exception occurred");
            foreach (var e in ex.InnerExceptions)
            {
                Console.WriteLine(e.Message);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Main Exception: {e.Message}");
        }
        finally
        {
            Console.WriteLine("Finish Application");
            ctx.Dispose();
        }
    }

    private async Task Run(string name, CancellationToken token)
    {
        while(true)
        {
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Task Cancelled");
                token.ThrowIfCancellationRequested();
            }
            Console.WriteLine($"Executing {name} ...");
            await Task.Delay(250, token);                
        }
    }
只引发一个异常,其他任务发生了什么?而且,
Console.WriteLine(“任务已取消”)
从未执行过

输出:

Starting application
Executing task1 ...
Executing task2 ...
Executing task2 ...
Executing task1 ...
Executing task1 ...
Executing task2 ...
Executing task2 ...
Executing task1 ...
Aggregate Exception occurred
A task was canceled.
Finish Application
两件事:

  • 您应该调用
    ex.flant().InnerExceptions
    查看以供参考
  • Task.Delay
    代替了您的取消逻辑。尝试将其包装在一个
    Try catch
    中进行日志记录。或者,您不能将
    令牌
    传递给
    任务。延迟

  • 如果您没有将CancellationToken传递给Task.Delay,那么您就失去了拥有CancellationToken的意义。@JoeWhite,我想您是有意义的,该建议是为了确保使用取消处理逻辑。@mrtig这很有帮助,但这是否意味着一旦发出取消令牌,所有任务都会正确终止?@WahabAkhtar正确的取消是您的逻辑需要协商的事情-无论是退出循环还是抛出错误例外。只有当您有逻辑来处理取消时,才会执行取消操作,包括将令牌传递给“Task.Delay”。