C# TaskCancellationTokenSource IsCancellationRequested 从未被捕获

Posted

技术标签:

【中文标题】C# TaskCancellationTokenSource IsCancellationRequested 从未被捕获【英文标题】:C# TaskCancellationTokenSource IsCancellationRequested never caught 【发布时间】:2019-01-03 18:05:26 【问题描述】:

谁能帮我理解取消任务的工作原理?我从docs.microsoft.com 中阅读了一些简单的示例,但我的实现没有按预期工作。

下面是我尝试使用的东西:

    private Task _Task  get; set; 

    private CancellationTokenSource _TaskCancellationTokenSource  get; set; 

    private void StartTask()
    
        _TaskCancellationTokenSource = new CancellationTokenSource();

        _Task = Task.Run(async () =>
        
            while (true)
            
                if(_TaskCancellationTokenSource.IsCancellationRequested)
                
                    Console.WriteLine("Canceling");

                    _TaskCancellationTokenSource.Token.ThrowIfCancellationRequested();
                

                Console.WriteLine("Running");

                await Task.Delay(10000, _TaskCancellationTokenSource.Token);
            
        , _TaskCancellationTokenSource.Token);
    

    private void StopTask()
    
        Console.WriteLine("Stoping task");
        _TaskCancellationTokenSource.Cancel();
        Console.WriteLine("Task stoped");
    

我在每 10 秒后调用 StartTask()。控制台按应有的方式写入“正在运行”。但是在调用 StopTask() 后,只会出现“正在停止的任务”和“已停止的任务”。 “取消”永远不会写入控制台。但是 VS 调试器显示在 Task 属性中已经被取消,“Running”再也不会出现了。

【问题讨论】:

...据我所知,您并没有在等待_Task...未处理的异常,包括取消,将被忽视。您如何以及何时致电StartTaskStopTask Task.Delay 会在检查前抛出 TaskCanceledException。 迈克你是对的。我改了:await Task.Delay(10000, _TaskCancellationTokenSource.Token);到:等待Task.Delay(10000); 【参考方案1】:

我认为调用 _TaskCancellationTokenSource.Cancel();在您的子线程中抛出某种异常。 (可能是TaskCanceledException)

尝试将您的任务代码包装在一个 try/catch 附件中,并在您的 catch 子句中显示您的消息。

【讨论】:

【参考方案2】:

谢谢各位。迈克在我的问题下方的评论是正确的。

Task.Delay 正在使用相同的取消令牌创建任务。

我把它改成:

await Task.Delay(3000, _TaskCancellationTokenSource.Token);

收件人:

await Task.Delay(3000);

它完全按照我的意愿工作。

【讨论】:

以上是关于C# TaskCancellationTokenSource IsCancellationRequested 从未被捕获的主要内容,如果未能解决你的问题,请参考以下文章

C#进阶C# 泛型

C#进阶C# 匿名方法

C#进阶C# 多线程

C# 教程

[C#教程01]C# 简介

用 C# 编写 C# 编译器,先有鸡还是先有蛋?