title: Why does TaskCanceledException occur?
body: <p>I have the following test code:</p>
  
  <pre><code>void Button_Click(object sender, RoutedEventArgs e)
  {
      var source = new CancellationTokenSource();
  
      var tsk1 = new Task(() =&gt; Thread1(source.Token), source.Token);
      var tsk2 = new Task(() =&gt; Thread2(source.Token), source.Token);
  
      tsk1.Start();
      tsk2.Start();
  
      source.Cancel();
  
      try
      {
          Task.WaitAll(new[] {tsk1, tsk2});
      }
      catch (Exception ex)
      {
          // here exception is caught
      }
  }
  
  void Thread1(CancellationToken token)
  {
      Thread.Sleep(2000);
  
      // If the following line is enabled, the result is the same.
      // token.ThrowIfCancellationRequested();
  }
  
  void Thread2(CancellationToken token)
  {
      Thread.Sleep(3000);
  }
  </code></pre>
  
  <p>In the thread methods I don't throw any exceptions, but I get <code>TaskCanceledException</code> in <code>try-catch</code> block of the outer code which starts the tasks. Why this happens and what is the purpose of <code>token.ThrowIfCancellationRequested();</code> in this case. I believe the exception should only be thrown if I call <code>token.ThrowIfCancellationRequested();</code> in the thread method.</p>