简体   繁体   English

为什么Task.IsCanceled不是真的?

[英]Why is Task.IsCanceled Not True?

I have a simple program here 我这里有一个简单的程序

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);
        }
    }

} 

Sample Output 样本输出
[00:00:00.0010000] - Main: Started [00:00:00.0010000]-主程序:已启动
[00:00:00.0040002] - Main: Started New Task [00:00:00.0040002]-主要:已开始新任务
[00:00:00.0060003] - Main: IsCanceled = [False] IsFaulted = [False] IsCompleted = [False] Status = [Running] [00:00:00.0060003]-Main:IsCanceled = [False] IsFaulted = [False] IsCompleted = [False]状态= [Running]
[00:00:00.0070004] - Task - [1]: Started [00:00:00.0070004]-任务-[1]:已开始
[00:00:01.0070576] - Main: Cancelling Task [00:00:01.0070576]-主程序:取消任务
[00:00:02.0071148] - Task - [1]: Cancellation Requested [00:00:02.0071148]-任务-[1]:请求取消
[00:00:03.0111722] - Main: After Cancelling Task [00:00:03.0111722]-主程序:取消任务后
[00:00:03.0111722] - Main: IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted] [00:00:03.0111722]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:03.0111722] - Main: Waiting For Task [00:00:03.0111722]-主程序:等待任务
[00:00:05.0112866] - Main: In Catch Block [00:00:05.0112866]-主要:在接球区
[00:00:05.0112866] - Main: IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted] [00:00:05.0112866]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:05.0112866] - Main: Received Exception In Task [The operation was canceled.] [00:00:05.0112866]-主操作:任务中收到异常[操作已取消。

I never see the Task.IsCanceled Set to true, am I making a mistake or missing something obvious. 我从没看到Task.IsCanceled设置为true,是我犯了一个错误还是遗漏了一些明显的东西。 I have done a bit of research/searching on this issue but was not able to find a conclusive answer. 我已经对此问题进行了一些研究/搜索,但是找不到最终的答案。

Note: Related Questions on StackOverFlow Cancellation of a task task IsCanceled is false, while I canceled Task.IsCancelled doesn't work 注意:有关StackOverFlow的相关问题取消任务 任务IsCanceled为false,而我取消了 Task.IsCancelled则不起作用

I suppose you should pass the CancellationToken to the constructor of OperationCanceledException . 我想您应该将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 will check whether both CancellationToken are same, if so it will mark task as Cancelled in your case it is not and so TPL assumes your task is not cancelled. TPL将检查两个CancellationToken是否相同,如果是这样,它将在您的情况下将其标记为“ Cancelled ,因此TPL假定您的任务未取消。

or even better use ThrowIfCancellationRequested method, as simple as that 甚至更好地使用ThrowIfCancellationRequested方法,就像那样简单

ct.ThrowIfCancellationRequested();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在任务中调用CancellationTokenSource.Cancel()不会将Task.IsCanceled设置为true - Calling CancellationTokenSource.Cancel() within a task does not set Task.IsCanceled to true 任务IsCanceled是假的,而我取消了 - task IsCanceled is false, while I canceled 预期 worker.ExecuteTask.IsCanceled 为 true,但发现为 False - Expected worker.ExecuteTask.IsCanceled to be true, but found False 我怎么知道Task.Isfaulted为什么是真的? - How can I see why Task.Isfaulted is true? 为什么要返回等待Task.FromResult(true); 而不是仅仅返回true? - Why return await Task.FromResult(true); instead of just return true? 为什么任务<httpresponsemessage> .Result 如果 Task 抛出异常<httpresponsemessage> .IsCompleted 是真的吗?</httpresponsemessage></httpresponsemessage> - Why does Task<HttpResponseMessage>.Result throw an exception if Task<HttpResponseMessage>.IsCompleted is true? 为什么Type.IsGenericType为Task返回TRUE,而没有通过方法的反射获得返回类型,但是typeof(Task).IsGenericTyp返回FALSE - Why does Type.IsGenericType return TRUE for Task without return type obtained by reflection from method but typeof(Task).IsGenericTyp returns FALSE .Net smtp SendMailAsync function 返回 IsCanceled - .Net smtp SendMailAsync function returns IsCanceled 检查是否有任务<bool>是真还是假(C#) - Check if Task<bool> is true or false (C#) 绑定任务 <T> 属性并将IsAsync设置为true - Binding to Task<T> property and seting IsAsync to true
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM