title: A pattern for self-cancelling and restarting task
body: <p>Is there a recommended established pattern for self-cancelling and restarting tasks?</p>
  
  <p>E.g., I'm working on the API for background spellchecker. The spellcheck session is wrapped as <code>Task</code>. Every new session should cancel the previous one and wait for its termination (to properly re-use the resources like spellcheck service provider, etc).</p>
  
  <p>I've come up with something like this:</p>
  
  <pre><code>class Spellchecker
  {
      Task pendingTask = null; // pending session
      CancellationTokenSource cts = null; // CTS for pending session
  
      // SpellcheckAsync is called by the client app
      public async Task&lt;bool&gt; SpellcheckAsync(CancellationToken token)
      {
          // SpellcheckAsync can be re-entered
          var previousCts = this.cts;
          var newCts = CancellationTokenSource.CreateLinkedTokenSource(token);
          this.cts = newCts;
  
          if (IsPendingSession())
          {
              // cancel the previous session and wait for its termination
              if (!previousCts.IsCancellationRequested)
                  previousCts.Cancel();
              // this is not expected to throw
              // as the task is wrapped with ContinueWith
              await this.pendingTask; 
          }
  
          newCts.Token.ThrowIfCancellationRequested();
          var newTask = SpellcheckAsyncHelper(newCts.Token);
  
          this.pendingTask = newTask.ContinueWith((t) =&gt; {
              this.pendingTask = null;
              // we don't need to know the result here, just log the status
              Debug.Print(((object)t.Exception ?? (object)t.Status).ToString());
          }, TaskContinuationOptions.ExecuteSynchronously);
  
          return await newTask;
      }
  
      // the actual task logic
      async Task&lt;bool&gt; SpellcheckAsyncHelper(CancellationToken token)
      {
          // do not start a new session if the the previous one still pending
          if (IsPendingSession())
              throw new ApplicationException("Cancel the previous session first.");
  
          // do the work (pretty much IO-bound)
          try
          {
              bool doMore = true;
              while (doMore)
              {
                  token.ThrowIfCancellationRequested();
                  await Task.Delay(500); // placeholder to call the provider
              }
              return doMore;
          }
          finally
          {
              // clean-up the resources
          }
      }
  
      public bool IsPendingSession()
      {
          return this.pendingTask != null &amp;&amp;
              !this.pendingTask.IsCompleted &amp;&amp;
              !this.pendingTask.IsCanceled &amp;&amp;
              !this.pendingTask.IsFaulted;
      }
  }
  </code></pre>
  
  <p>The client app (the UI) should just be able to call <code>SpellcheckAsync</code> as many times as desired, without worrying about cancelling a pending session. The main <code>doMore</code> loop runs on the UI thread (as it involves the UI, while all spellcheck service provider calls are IO-bound).</p>
  
  <p>I feel a bit uncomfortable about the fact that I had to split the API into two peices, <code>SpellcheckAsync</code> and <code>SpellcheckAsyncHelper</code>, but I can't think of a better way of doing this, and it's yet to be tested.</p>