title: Associate a CancellationToken with an async method's Task
body: <p>Question: Is there a way to associate a <code>CancellationToken</code> with the <code>Task</code> returned from an <code>async</code> method?</p>
  <p>Generally, a <code>Task</code> will end up in the <code>Canceled</code> state if an <code>OperationCancelledException</code> is thrown with a <code>CancellationToken</code> matching the <code>Task</code>'s <code>CancellationToken</code>.  If they don't match, then the task goes into the <code>Faulted</code> state:</p>
  <pre><code>void WrongCancellationTokenCausesFault()
  {
      var cts1 = new CancellationTokenSource();
      var cts2 = new CancellationTokenSource();
      cts2.Cancel();
  
      // This task will end up in the Faulted state due to the task's CancellationToken
      // not matching the thrown OperationCanceledException's token.
      var task = Task.Run(() =&gt; cts2.Token.ThrowIfCancellationRequested(), cts1.Token);  
  }
  </code></pre>
  <p>With <code>async</code>/<code>await</code>, I haven't found a way to set the method's <code>Task</code>'s <code>CancellationToken</code> (and thus achieve the same sort of functionality).  From my testing, it seems that <em>any</em> <code>OperationCancelledException</code> will cause the <code>async</code> method to enter the Cancelled state:</p>
  <pre><code>async Task AsyncMethodWithCancellation(CancellationToken ct)
  {
      // If ct is cancelled, this will cause the returned Task to be in the Cancelled state
      ct.ThrowIfCancellationRequested(); 
      await Task.Delay(1);
  
      // This will cause the returned Task to be in the Cancelled state
      var newCts = new CancellationTokenSource();
      newCts.Cancel();
      newCts.Token.ThrowIfCancellationRequested();
  }
  </code></pre>
  <p>It would be nice to have a little more control, since if a method I call from my <code>async</code> method is cancelled (and I don't expect cancellation--i.e. its not this <code>Task</code>'s <code>CancellationToken</code>), I would expect the task to enter the <code>Faulted</code> state--not the <code>Canceled</code> state.</p>