title: why task's status is "Faulted" not "Canceled" in cooperative cancellation?
body: <p>My question is based on the answer to this <a href="https://stackoverflow.com/a/3713113/9623401">question</a></p>
  <p>Let's say we have the following code:</p>
  <pre class="lang-cs prettyprint-override"><code>class Program 
  {
      static void Main(string[] args) 
      {
          CancellationTokenSource cts = new CancellationTokenSource();
          Task&lt;Int32&gt; t = Task.Run(() =&gt; Sum(cts.Token, 100000));     
          
          // make sure the the task run first before 
          Thread.Sleep(500);   
          cancellation request occurs
          cts.Cancel();
        
          var status = t.Status;  // status is &quot;Faulted&quot;
          Console.ReadLine();
      }
  
      static Int32 Sum(CancellationToken ct, Int32 n) 
      {
          Int32 sum = 0;
          for (; n &gt; 0; n--) 
          {
              // throws
              ct.ThrowIfCancellationRequested();    
  
              OperationCanceledException if cancellation request occurs
              checked { sum += n; } 
          }
          return sum;
      }
  }
  </code></pre>
  <p>We can see that <code>t</code>'s status is &quot;Faulted&quot; which is good.</p>
  <p>Accoridng to the answer to the question, when we pass the token into task's constructor or Run's parameter, <code>t</code>'s status should be &quot;Canceled&quot; becuase</p>
  <blockquote>
  <p>when the task sees that OperationCanceledException, it checks whether the OperationCanceledException's token matches the Task's token. If it does, that exception is viewed as an acknowledgement of cooperative cancellation and the Task transitions to the Canceled state (rather than the Faulted state)</p>
  </blockquote>
  <p>but even if we pass the token as</p>
  <pre class="lang-cs prettyprint-override"><code>class Program 
  {
      static void Main(string[] args) 
      {
          CancellationTokenSource cts = new CancellationTokenSource();
          
          // pass the token into Run() method as the second parameter
          Task&lt;Int32&gt; t = Task.Run(() =&gt; Sum(cts.Token, 100000), cts.Token);     
          Thread.Sleep(500);
          cts.Cancel();
  
          // status is still &quot;Faulted&quot;, not &quot;Canceled&quot;
          var status = t.Status;  
          Console.ReadLine();
      }
     ...
  }
  </code></pre>
  <p><code>t</code>'s status is still &quot;Faulted&quot; not &quot;Canceled&quot;, so did I misunderstand the answer to the question or did I do sth wrong in the code?</p>