如何使用CancellationToken取消任务? [英] How to cancel a Task using CancellationToken?

查看:401
本文介绍了如何使用CancellationToken取消任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这段代码:

//CancelationToken
CancellationTokenSource src = new CancellationTokenSource();
CancellationToken ct = src.Token;
ct.Register(() => Console.WriteLine("Abbruch des Tasks"));
//Task
Task t = new Task(() =>
{
    System.Threading.Thread.Sleep(1000);
    if (ct.IsCancellationRequested)
    {
        try
        {
            //Throw
            ct.ThrowIfCancellationRequested();                        
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine(
                "ThrowIfCancellationRequested() liefert eben eine Exception");
        }
    }             

}, ct);
//Run Task and Cancel
t.Start();
src.CancelAfter(350);
t.Wait();

// Get Information
Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}",
                    t.IsCanceled, t.IsCompleted, t.IsFaulted);

因此,在这种情况下,我取消了Task,但最终输出是:
已取消:False。已完成:True。错误:False

So in this case I canceled my Task but my output in the end is: "Canceled: False . Finished: True . Error: False"

在我看来,它应该为 Canceled:True。Finished:False。
为什么会得到这个结果?因为我试图捕捉异常?

In my opinion it should be "Canceled:True . Finished:False". Why do I get this result? Because I try to catch the exception?

我尝试了没有try-catch块的尝试,但是由于OperationCanceledException,我的程序停止了。有人可以帮我吗?

I've tried it without the try - catch block, but then my program stops because of the OperationCanceledException. Can somebody help me?

推荐答案

您吞下了异常,因此当您实际处理异常时,该任务被标记为已完成并且不会向外传播。

You're swallowing the exception, thus the task is flagged as finished as you actually handle the exception and it doesn't propagate outwards.

相反,不要在委托内部捕获异常,而在外部捕获:

Instead, don't catch the exception inside the delegate, catch it outside:

void Main()
{
    CancellationTokenSource src = new CancellationTokenSource();
    CancellationToken ct = src.Token;
    ct.Register(() => Console.WriteLine("Abbruch des Tasks"));

    Task t = Task.Run(() =>
    {
        System.Threading.Thread.Sleep(1000);
        ct.ThrowIfCancellationRequested();
    }, ct);

    src.Cancel();
    try
    {
        t.Wait();
    }
    catch (AggregateException e)
    {
        // Don't actually use an empty catch clause, this is
        // for the sake of demonstration.
    }

    Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}",
                       t.IsCanceled, t.IsCompleted, t.IsFaulted);
}

这篇关于如何使用CancellationToken取消任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆