title: Can I dispose CancellationTokenSource before Task be cancelled?
body: <p>can I dispose <code>CancellationTokenSource</code> before <code>Task</code> be cancelled? If not, why?</p>
  
  <p><strong>Code 1</strong> (from <a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation" rel="nofollow noreferrer">Task Cancellation</a>. I made some minor changes for simplification) seems to recommend to wait <code>Task</code> before disposing <code>CancellationTokenSource</code>. If so, the <code>Dispose</code> method of the class containing <code>CancellationTokenSource</code> will be more complicated than I hope it to be.</p>
  
  <p>On my PC, <strong>Code 2</strong> seems to be working properly, too. Can I use this pattern instead?</p>
  
  <p><strong>Code 1: Dispose AFTER Cancellation Complete</strong>
  </p>
  
  <pre><code>    [STAThread]
      private static void Main() {
          var tokenSource2 = new CancellationTokenSource();
          var task = DoAsync(tokenSource2.Token);
          tokenSource2.Cancel();
          tokenSource2 = null;
  
          try {
              task.Wait();
          }
          catch (AggregateException e) {
              foreach (var v in e.InnerExceptions)
                  Console.WriteLine(e.Message + " " + v.Message);
          }
          finally {
              tokenSource2.Dispose();
          }
  
          Console.ReadKey();
      }
  
      private static async Task DoAsync(CancellationToken token) {
          while (true) {
              await Task.Delay(10000).ConfigureAwait(true);
              token.ThrowIfCancellationRequested();
          }
      }
  </code></pre>
  
  <p><strong>Code 2: Dispose BEFORE Cancellation Complete</strong></p>
  
  <pre><code>    [STAThread]
      private static void Main() {
          var tokenSource2 = new CancellationTokenSource();
          var task = DoAsync(tokenSource2.Token);
          tokenSource2.Cancel();
          tokenSource2.Dispose();
  
          try {
              task.Wait();
          }
          catch (AggregateException e) {
              foreach (var v in e.InnerExceptions)
                  Console.WriteLine(e.Message + " " + v.Message);
          }
          finally {
              //// tokenSource2.Dispose();
          }
  
          Console.ReadKey();
      }
  
      private static async Task DoAsync(CancellationToken token) {
          while (true) {
              await Task.Delay(10000).ConfigureAwait(true);
              token.ThrowIfCancellationRequested();
          }
      }
  </code></pre>
  
  <h1>EDIT: My case</h1>
  
  <p>Actually I'm wondering whether I have to <code>Wait</code> for task cancellation in <code>Dispose</code> method.</p>
  
  <pre><code>    public class Class1 : IDisposable {
          //// tokenSource for calculationTask
          private CancellationTokenSource tokenSource;
  
          //// background calculation task
          private Task calculationTask;
  
          public void Dispose() {
              tokenSource?.Cancel();
              //// calculationTask.Wait(); Should I wait for task completion?
              tokenSource?.Dispose();
              tokenSource = null;
  
              calculationTask = null;
          }
      }
  </code></pre>