c# - 取消时的任务状态

标签 c# task-parallel-library

我写了下面的代码:

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;

int i = 0;
Console.WriteLine("Calling from Main Thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);

Task t1 = new Task(() =>
{
    while (true)
    {
        try
        {
            token.ThrowIfCancellationRequested();
        }

        catch (OperationCanceledException)
        {
            Console.WriteLine("Task1 cancel detected");
            break;
        }

        Console.WriteLine("Task1: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++);
    }
}, token);

Task t2 = new Task(() =>
{
    while (true)
    {
        try
        {
            token.ThrowIfCancellationRequested();
        }

        catch (OperationCanceledException)
        {
            Console.WriteLine("Task2 cancel detected");
            break;
        }

        Console.WriteLine("Task2: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++);
    }
});

t1.Start();
t2.Start();
Thread.Sleep(100);
tokenSource.Cancel();

t1.Wait();//wait for thread to completes its execution
t2.Wait();//wait for thread to completes its execution
Console.WriteLine("Task1 Status:{0}", t1.Status);
Console.WriteLine("Task2 Status:{0}", t1.Status);

这里我正在取消任务然后状态也显示 RanToCompletion 但是如果我删除等待这两个任务,那么它会显示我已取消状态...

因为我正在取消任务,所以我希望在任何情况下都处于取消状态...

编辑:来自 MSDN 通过抛出 OperationCanceledException 并将请求取消的 token 传递给它。执行此操作的首选方法是使用 ThrowIfCancellationRequested 方法。以这种方式取消的任务会转换为 Canceled 状态,调用代码可以使用该状态来验证任务是否响应了它的取消请求。

如果您不使用 Wait 或 WaitAll 方法来等待任务,则任务只会将其状态设置为已取消。

最佳答案

当您捕获 OperationCanceledException 并跳出 while 循环时,任务正常结束并且任务状态将为 RanToCompletion。

为了获得 Canceled 状态,您需要重新抛出 OperationCanceledException 或根本不捕获它。

根据 MSDN在以下情况下,任务状态将被取消:

The task acknowledged cancellation by throwing an OperationCanceledException with its own CancellationToken while the token was in signaled state, or the task's CancellationToken was already signaled before the task started executing. For more information, see Task Cancellation.

由于您在源代码中吞下了异常,因此任务状态将为 RanToCompletion。

要回答你关于为什么取消等待时状态为取消的问题,可能是因为尚未捕获异常并且在较早的时间检查了取消状态。 不应将此行为视为可靠和可重现的。

关于c# - 取消时的任务状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12129936/

相关文章:

c# - 我们需要让 "double"等待 GUI 才不会卡住?

.net - 默认情况下,F# 是否在内部使代码并行运行?

c# - WPF 中的并行任务

multithreading - Golang : How to capture return values of massively parallel benchmark (> 1 million tasks)?

c# - ASP.NET MVC 如何将 ModelState 错误转换为 json

c# - 是否可以调用参数为 'lambda expression' 的方法?

c# - Unity - 使用新输入系统/角色 Controller 让角色看着鼠标

c# - WCF 使用自定义 ApplicationPool Identity 慢 3 倍

c# - 如何覆盖现有的扩展方法

c# - for 循环和 Parallel.For() 之间的性能损失(MaxDegreeOfParallelism 为 1)