簡體   English   中英

為什么Task.IsCanceled不是真的?

[英]Why is Task.IsCanceled Not True?

我這里有一個簡單的程序

private static void CancellingSingleTask()
{
    DateTime whenStarted = DateTime.Now;

    Console.WriteLine("[{0}] - Main: Started", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken ct = cts.Token;

    Task task = Task.Factory.StartNew(() => 
    {
        int? taskId = Task.CurrentId;

        Console.WriteLine("[{0}] - Task - [{1}]:  Started", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);

        Thread.Sleep(2000);

        if (ct.IsCancellationRequested)
        {
            Console.WriteLine("[{0}] - Task - [{1}]:  Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
            throw new OperationCanceledException();
        }
        Console.WriteLine("[{0}] - Task - [{1}]:  No Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
    }, ct);

    Action Print = () =>
    {
        Console.WriteLine("[{0}] - Main: Task.IsCanceled = [{1}]  Task.IsFaulted = [{2}] Task.IsCompleted = [{3}] Task.Status = [{4}]", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks),
            task.IsCanceled, task.IsFaulted, task.IsCompleted, task.Status);
    };

    Console.WriteLine("[{0}] - Main: Started New Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
    Print();

    Thread.Sleep(1000);

    Console.WriteLine("[{0}] - Main: Cancelling Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));

    cts.Cancel();

    Thread.Sleep(2000);

    Console.WriteLine("[{0}] - Main: After Cancelling Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
    Print();

    try
    {
        Console.WriteLine("[{0}] - Main: Waiting For Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));

        task.Wait();

        Console.WriteLine("[{0}] - Main: After Waiting For Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
        Print();
    }
    catch (AggregateException aggregateException)
    {
        Thread.Sleep(2000);
        Console.WriteLine("[{0}] - Main: In Catch Block", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
        Print();

        foreach (var exception in aggregateException.InnerExceptions)
        {
            Console.WriteLine("[{0}] - Main: Received Exception In Task [{1}]", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), exception.Message);
        }
    }

} 

樣本輸出
[00:00:00.0010000]-主程序:已啟動
[00:00:00.0040002]-主要:已開始新任務
[00:00:00.0060003]-Main:IsCanceled = [False] IsFaulted = [False] IsCompleted = [False]狀態= [Running]
[00:00:00.0070004]-任務-[1]:已開始
[00:00:01.0070576]-主程序:取消任務
[00:00:02.0071148]-任務-[1]:請求取消
[00:00:03.0111722]-主程序:取消任務后
[00:00:03.0111722]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:03.0111722]-主程序:等待任務
[00:00:05.0112866]-主要:在接球區
[00:00:05.0112866]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:05.0112866]-主操作:任務中收到異常[操作已取消。

我從沒看到Task.IsCanceled設置為true,是我犯了一個錯誤還是遺漏了一些明顯的東西。 我已經對此問題進行了一些研究/搜索,但是找不到最終的答案。

注意:有關StackOverFlow的相關問題取消任務 任務IsCanceled為false,而我取消了 Task.IsCancelled則不起作用

我想您應該將CancellationToken傳遞給OperationCanceledException的構造函數。

  if (ct.IsCancellationRequested)
    {
        Console.WriteLine("[{0}] - Task - [{1}]:  Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
        throw new OperationCanceledException(ct);
    }

TPL將檢查兩個CancellationToken是否相同,如果是這樣,它將在您的情況下將其標記為“ Cancelled ,因此TPL假定您的任務未取消。

甚至更好地使用ThrowIfCancellationRequested方法,就像那樣簡單

ct.ThrowIfCancellationRequested();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM