title: Pattern for long-running operation with cancellation ability
body: <p>In order to perform long-running (let it be search in this context) operation, I put the loading logic inside a TPL task, so the general method <strong>Search()</strong> is called on background thread. <strong>Search()</strong> operation can be long enough, so I need the ability to cancel it properly, using the <strong><a href="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken%28v=vs.100%29.aspx" rel="nofollow">CancellationToken</a></strong>.  But the <strong>Search()</strong> operation did not return until it finished, so I have to do some logic in order to implement convenient and <strong>(!) fast</strong> cancellation.</p>
  
  <p>Using <strong><a href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle%28v=vs.100%29.aspx" rel="nofollow">WaitHandle's</a></strong> I can implement something like this:</p>
  
  <pre><code>private void StartSearch() // UI thread
  {
      CancellationTokenSource s = new CancellationTokenSource();
      Task.Factory.StartNew(() =&gt; StartSearchInternal(s.Token), s.Token)
  }
  
  private void StartSearchInternal(CancellationToken token) // Main Background Thread
  {
      ManualResetEvent eHandle = new ManualResetEvent(false);
      Task.Factory.StartNew(() =&gt; Search(eHandle ), TaskScheduler.Default);
      WaitHandle.WaitAny(new [] { eHandle, token.WaitHandle });
      token.ThrowIfCancellationRequested();
  }
  
  private IEnumerable&lt;object&gt; Search(ManualResetEvent e) // Another Background thread
  {
      try
      {
          // Real search call, i.e. to database, service, or AD, doesn't matter
          return RealSearch();
      }
      catch {} // Here, for simplicity of question, catch and eat all exceptions
      finally
      {
          try
          {
              e.Set();
          }
          catch {} 
      }
  }
  </code></pre>
  
  <p>It's seems to me that this is not so elegant solution, that can be made.</p>
  
  <p><strong>Q:</strong> Is there any other approaches for this task?</p>