title: Backgroundworker.CancelAsync() not working
body: <p>I have a backgroundworker that runs a single process. I want to be able to cancel the processing while it's going, but when I call the CancelAsync() method, it never actually cancels. Where am I wrong?</p>
  
  <p>Here's the DoWork() method:</p>
  
  <pre><code>        private void bgw_DoWork(object sender, DoWorkEventArgs e)
      {
          BackgroundWorker b = sender as BackgroundWorker;
  
          if (b != null)
          {
               if (!b.CancellationPending)
              {
                  try
                  {
                      // Let's run the process as a backgroundworker so we have the ability to cancel the search, and/or be able to view results while it's still searching
                      ProcessParameters pp = e.Argument as ProcessParameters;
  
                      if (pp.DoReplace)
                          results = FindReplace.FindReplace.FindAndReplace(pp.PathToSearch, pp.FindText, pp.ReplaceText, pp.UseRegularExpressions, pp.IncludeList, pp.ExcludeList, pp.RecurseSubdirectories, pp.IgnoreCase);
                      else
                          results = FindReplace.FindReplace.Find(pp.PathToSearch, pp.FindText, pp.UseRegularExpressions, pp.IncludeList, pp.ExcludeList, pp.RecurseSubdirectories, pp.IgnoreCase);
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.ToString());
                  }
              }
              else
              {
                  // Cancel was clicked
                  e.Cancel = true;
              }
          }
      }
  </code></pre>
  
  <p>Here's the method that starts the processing:</p>
  
  <pre><code>        private void btnGo_Click(object sender, EventArgs e)
      {
          if (btnGo.Text == "Cancel")
          {
              if (DialogResult.Yes == MessageBox.Show("Are you sure you wish to cancel?", "Cancel Requested", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                  bgw.CancelAsync();
  
              return;
          }
  
          if (tbFind.Text.Length == 0)
          {
              MessageBox.Show("Find text is not valid.");
              return;
          }
  
          tbFound.Text = String.Empty;
          tbFoundInThisFile.Text = String.Empty;
          lvResults.Items.Clear();
          includeList = null;
          excludeList = null;
          results = null;
  
          if (radDirectory.Checked &amp;&amp; !radFile.Checked)
          {
              includeList = BuildIncludeExcludeList(tbIncludeFiles.Text);
              excludeList = BuildIncludeExcludeList(tbExcludeFiles.Text);
          }
  
          ProcessParameters pp = null;
  
          if (chkReplace.Checked)
              pp = new ProcessParameters(tbPath.Text, tbFind.Text, tbReplace.Text, chkUseRegEx.Checked, includeList, excludeList, chkRecursion.Checked, chkIgnoreCase.Checked, true);
          else
              pp = new ProcessParameters(tbPath.Text, tbFind.Text, chkUseRegEx.Checked, includeList, excludeList, chkRecursion.Checked, chkIgnoreCase.Checked, false);
  
          bgw.RunWorkerAsync(pp);
  
          // Toggle fields to locked while it's running
          btnGo.Text = "Cancel";
      }
  </code></pre>
  
  <p>And here's the WorkerCompleted() event:</p>
  
  <pre><code>        private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
          btnGo.Text = "Go";
  
          string message = String.Empty;
          const string caption = "FindAndReplace is Complete";
  
          if (!e.Cancelled)
          {
              if (results != null)
              {
                  tbFound.Text = results.Found.ToString();
                  tbSearched.Text = results.FilesSearched.ToString();
                  tbSkipped.Text = results.FilesSkipped.ToString();
  
                  message = String.Format("Search finished resulting in {0} match(es).", results.Found);
              }
              else
                  message = "The FindAndReplace results were empty. The process was cancelled or there was an error during operation.";
          }
          else
              message = "The FindAndReplace process was cancelled.";
  
          if (e.Error != null)
              message += String.Format("{0}{0}There was an error during processing: {1}", Environment.NewLine, e.Error);
  
          MessageBox.Show(message, caption);
      }
  </code></pre>