C# 取消时的任务状态

C# 取消时的任务状态,c#,task-parallel-library,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

我编写了以下代码:

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);
这里我正在取消任务,然后状态也显示为RANTO完成,但是如果我删除了两个任务上的等待,那么它会显示我已取消状态

当我取消任务时,我希望在任何情况下都会出现取消状态

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


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

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

为了获得取消状态,您需要重新播放OperationCanceledException或根本不捕获它

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

任务通过抛出 OperationCanceledException具有自己的CancellationToken,而 令牌处于信号状态,或者任务的CancellationToken处于 在任务开始执行之前已发出信号。更多 有关详细信息,请参阅

由于您已经在源代码中包含了异常,因此任务状态将是RanToCompletion


要回答您关于在删除等待时为何取消状态的问题,可能是因为尚未捕获异常,并且已在较早的时间检查了取消状态这种行为不应被认为是可靠和可复制的。

谢谢ziad。但是当我删除任务的等待时,我得到的是取消状态,这造成了一些混乱。更新了MSDN链接中的问题:仍然对我更新的语句感到困惑。这与你的上一句话相矛盾吗?@RaoBHavik我认为当你等待时状态被取消完全是巧合。事实上,如果用Thread.Sleep(5000)替换这两个waitis,任务状态可能是RanToCompletion。