为什么任务的状态是“故障”而不是“已取消”?

问题描述 投票:0回答:1

我正在尝试不同的取消方式。在这里您将看到 5 种不同的方法,前四种方法是毫无疑问的。 (这些内容已被评论,但保留以避免讨论)。 我想了解最后一种方法(如下所示的方法5):

using static System.Console;

WriteLine("Simple cancellation demonstration.");

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;

// This token is used for a follow-up question
var token2 = tokenSource.Token;

var printTask = Task.Run
 (
  () =>
  {
      // A loop that runs 100 times
      for (int i = 0; i < 100; i++)
      {
          // Approach-1 :(Will cause RanToCompletion)
          //if (token.IsCancellationRequested)
          //{
          //    WriteLine("Cancelling the print activity.");
          //    // Do some cleanups, if required
          //    return;
          //}
          //// Approach-2
          //if (token.IsCancellationRequested)
          //{
          //    WriteLine("Cancelling the print activity.");
          //    // Do some cleanups, if required
          //    throw new OperationCanceledException(token);
          //}
          // Approach-3
          // token.ThrowIfCancellationRequested();

          //// Approach 4
          //if (token.IsCancellationRequested)
          //{
          //    // Do some cleanups, if required
          //    token.ThrowIfCancellationRequested();
          //}
          // Approach 5
          if (token.IsCancellationRequested)
          {
              WriteLine("Cancelling the print activity.");
                throw new OperationCanceledException("Raised a  cancellation request"); // Causing Faulted state
              // throw new OperationCanceledException(); // Causing Faulted state also              
          }

          WriteLine($"{i}");
          // Imposing the sleep to make some delay
          Thread.Sleep(500);
      }
  }, token
);

WriteLine("Enter c to cancel the task.");
char ch = ReadKey().KeyChar;
if (ch.Equals('c'))
{
    WriteLine("\nTask cancellation requested.");
    tokenSource.Cancel();
}

// Wait till the task finishes the execution[ Not for production code]
while (!printTask.IsCompleted) { }

WriteLine($"The final status of printTask is: {printTask.Status}");
WriteLine("End of the main thread.");
Here is a sample output:
    Simple cancellation demonstration.
    Enter c to cancel the task.
    0
    1
    2
    c
    Task cancellation requested.
    Cancelling the print activity.
    The final status of printTask is: Faulted
    End of the main thread.

因此,我可以看到,当我不将令牌作为参数传递时(在异常内部),状态为“Faulted”,但未取消。现在我有以下问题: 1.这是预期的行为吗?

2.在线链接:https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation指出:

如果令牌的 IsCancellationRequested 属性返回 false,或者异常的令牌与任务的令牌不匹配,则将 OperationCanceledException 视为正常异常,从而导致任务转换为“Faulted”状态。

但是当我传递不同的令牌时,状态显示为“已取消”,但不是“故障”。为了测试这一点,我使用了以下块:

if (token.IsCancellationRequested)
{
    WriteLine("Cancelling the print activity.");
     // throw new OperationCanceledException("Raised a  cancellation request"); // Causing Faulted state
    // throw new OperationCanceledException(); // Causing Faulted state also
     throw new OperationCanceledException(token2); // Causing Canceled state  
}

--请让我知道我在这里缺少哪些基础知识?

c# task task-parallel-library .net-8.0
1个回答
0
投票

因为token和token2是同一个token。

© www.soinside.com 2019 - 2024. All rights reserved.