Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么任务没有';不显示已取消状态_C#_Async Await_Task Parallel Library_Task - Fatal编程技术网

C# 为什么任务没有';不显示已取消状态

C# 为什么任务没有';不显示已取消状态,c#,async-await,task-parallel-library,task,C#,Async Await,Task Parallel Library,Task,我正在测试一个在Linqpad上创建的简单控制台应用程序,其目的是确保了解任务的工作情况,并创建一个在任务完成、出现故障或取消时工作的逻辑。我只想在任务完成但没有出现故障或取消时执行逻辑 void Main() { CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000)); Task t = Task.Run(() => Work(),cts.Token);

我正在测试一个在Linqpad上创建的简单控制台应用程序,其目的是确保了解
任务的工作情况,并创建一个在
任务
完成、出现故障或取消时工作的逻辑。我只想在任务完成但没有出现故障或取消时执行逻辑

void Main()
{
    CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000));

    Task t = Task.Run(() => Work(),cts.Token);
    try
    {
        t.Wait();
    }
    catch
    {
    }

    ("Completed :: " + t.IsCompleted).Dump();
    ("Canceled :: " + t.IsCanceled).Dump();
    ("Faulted :: " + t.IsFaulted).Dump();
}

public async Task Work()
{
    await Task.Delay(3000);
}
以下是问题:

  • 我能够自信地找出已完成和出现故障的状态,但即使在我看来此代码应导致任务取消时,
    IsCanceled
    属性的值始终为false

  • 理想情况下,当任务出现故障时,即使我在try-catch块中静默捕获异常,它应该将
    IsCompleted
    显示为false,但它始终保持为true,当前Linqpad没有继续出错选项,但我假设,如果我可以继续出错,它将变为false


  • 您没有将
    CancellationToken
    传递给
    Task.Delay
    方法,因此不需要取消任何内容。 如果令牌有未完成的取消,您在
    Task.Run(xxx)
    中传递的令牌将阻止工作启动。但是您的令牌在1秒后被取消,这是在调用
    任务很久之后。运行

    试试这个:

    void Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0, 0, 0, 0, 1000));
    
        Task t = Task.Run(() => Work(cts.Token), cts.Token);
        try
        {
            t.Wait();
        }
        catch
        {
        }
    
        ("Completed :: " + t.IsCompleted).Dump();
        ("Canceled :: " + t.IsCanceled).Dump();
        ("Faulted :: " + t.IsFaulted).Dump();
    }
    
    public async Task Work(CancellationToken t)
    {
        await Task.Delay(3000, t);
    }
    
    我能够自信地找出已完成和故障状态,但即使在我看来,这段代码应该导致任务取消,IsCanceled属性的值始终为false

    取消没有自动性。您正在将
    CancellationToken
    传递给
    任务。运行
    。如果在任务启动时取消,则启动过程将因取消而中断。任务运行后,任务的方法负责检查取消令牌<代码>等待
    没有这样做。它甚至不知道取消令牌。因此,任务永远不能变为取消状态

    以下是您观察取消的方式:

    void Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000));
    
        Task t = Task.Run(() => Work(cts.Token),cts.Token);
        try
        {
            t.Wait();
        }
        catch
        {
        }
    
        ("Completed :: " + t.IsCompleted).Dump();
        ("Canceled :: " + t.IsCanceled).Dump();
        ("Faulted :: " + t.IsFaulted).Dump();
    }
    
    public async Task Work(CancellationToken token)
    {
        await Task.Delay(3000, token);
    }
    
    理想情况下,当任务出现故障时,即使我在try-catch块中静默捕获异常,它也应该显示IsCompleted为false,但它始终保持为true

    检查:

    当任务处于三种最终状态之一时,IsCompleted将返回true:RanToCompletion、Faulted或Canceled


    其他人注意到,您的代码没有观察到
    取消令牌
    ,这就是任务没有被取消的原因

    我将回答这部分问题:

    我只想在任务完成但没有出现故障或取消时执行逻辑

    void Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000));
    
        Task t = Task.Run(() => Work(),cts.Token);
        try
        {
            t.Wait();
        }
        catch
        {
        }
    
        ("Completed :: " + t.IsCompleted).Dump();
        ("Canceled :: " + t.IsCanceled).Dump();
        ("Faulted :: " + t.IsFaulted).Dump();
    }
    
    public async Task Work()
    {
        await Task.Delay(3000);
    }
    
    为此,请将逻辑放在等待任务之后:

    await t;
    // Your logic here.
    

    IsCanceled
    /
    IsFaulted
    /
    IsCompleted
    用于控制流是一种代码气味。

    取消是合作的。您的任务忽略了您的取消令牌,而是选择运行到完成。因此,它没有被取消。我应该做什么修改才能使这项工作正常进行,我的其他理解是否正确,如果异常传播,那么它应该被认为是未完成的错误?感谢全面的详细信息和回答所有问题谢谢回答,感谢,重要细节请帮助Hanks@StephenCleary,事实上,我的代码就是这样的,我在
    列表中有许多不同的
    任务
    ,我调用了
    等待任务。当所有(任务列表)
    时,我没有意识到这会向调用者抛出底层任务中的任何异常,我认为这会悄悄地嵌入异常,我需要明确指出哪些任务包含有效结果,哪些任务出错/取消,但正如您所澄清的,当使用wait展开时,这是不正确的