取消时的任务状态

时间:2012-08-26 11:58:37

标签: 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并向其传递请求取消的令牌。执行此操作的首选方法是使用ThrowIfCancellationRequested方法。以这种方式取消的任务将转换为Canceled状态,调用代码可以使用该状态验证任务是否响应了其取消请求。

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

1 个答案:

答案 0 :(得分:6)

当您捕获OperationCanceledException并且跳出while循环时,任务正在优雅地结束,任务状态将是RanToCompletion。

为了获得“已取消”状态,您需要重新抛出OperationCanceledException或者根本不捕获它。

根据MSDN,任务状态将在以下时间取消:

  

任务承认通过投掷取消取消   OperationCanceledException具有自己的CancellationToken而   令牌处于信号状态,或者任务的CancellationToken是   在任务开始执行之前已经发出信号。更多   信息,请参阅Task Cancellation

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

要在删除等待时回答有关“状态”被取消的原因的问题,可能是因为尚未捕获异常,并且已在较早时间检查取消状态。 此行为不应被视为可靠且可重现。