title: Cancel Async Task from a button
body: <p>What I need to do is be able to cancel a task that is running async.</p>
  
  <p>I have been searching and cannot seem to wrap my head around it. I just cant seem to discern how it would be implemented into my current setup.</p>
  
  <p>Here is my code that fires my task off. Any help on where or how to implement a cancellation token would be greatly appreciated.</p>
  
  <pre><code>    private async void startThread()
      {
          //do ui stuff before starting
          ProgressLabel.Text = String.Format("0 / {0} Runs Completed", index.Count());
          ProgressBar.Maximum = index.Count();
  
          await ExecuteProcesses();
  
          //sort list of output lines
          outputList = outputList.OrderBy(o =&gt; o.RunNumber).ToList();
  
          foreach (Output o in outputList)
          {
              string outStr = o.RunNumber + "," + o.Index;
              foreach (double oV in o.Values)
              {
                  outStr += String.Format(",{0}", oV);
              }
  
              outputStrings.Add(outStr);
          }
  
          string[] csvOut = outputStrings.ToArray();
  
          File.WriteAllLines(settings.OutputFile, csvOut);
          //do ui stuff after completing.
  
          ProgressLabel.Text = index.Count() + " runs completed. Output written to file test.csv";
      }
  
      private async Task ExecuteProcesses()
      {
          await Task.Factory.StartNew(() =&gt;
          {
              int myCount = 0;
              int maxRuns = index.Count();
              List&lt;string&gt; myStrings = index;
              Parallel.ForEach(myStrings,
                  new ParallelOptions()
                  {
                      MaxDegreeOfParallelism = settings.ConcurrentRuns
                  }, (s) =&gt;
                  {
                      //This line gives us our run count.
                      int myIndex = myStrings.IndexOf(s) + 1;
  
                      string newInputFile = Path.Combine(settings.ProjectPath + "files/", Path.GetFileNameWithoutExtension(settings.InputFile) + "." + s + ".inp");
                      string newRptFile = Path.Combine(settings.ProjectPath + "files/", Path.GetFileNameWithoutExtension(settings.InputFile) + "." + s + ".rpt");
  
                      try
                      {
                          //load in contents of input file
                          string[] allLines = File.ReadAllLines(Path.Combine(settings.ProjectPath, settings.InputFile));
  
  
                          string[] indexSplit = s.Split('.');
  
                          //change parameters here
                          int count = 0;
                          foreach (OptiFile oF in Files)
                          {
                              int i = Int32.Parse(indexSplit[count]);
                              foreach (OptiParam oP in oF.Parameters)
                              {
                                  string line = allLines[oP.LineNum - 1];
                                  if (oP.DecimalPts == 0)
                                  {
                                      string sExpression = oP.Value;
                                      sExpression = sExpression.Replace("%i", i.ToString());
                                      EqCompiler oCompiler = new EqCompiler(sExpression, true);
                                      oCompiler.Compile();
                                      int iValue = (int)oCompiler.Calculate();
  
                                      allLines[oP.LineNum - 1] = line.Substring(0, oP.ColumnNum - 1) + iValue.ToString() + line.Substring(oP.ColumnNum + oP.Length);
                                  }
                                  else
                                  {
                                      string sExpression = oP.Value;
                                      sExpression = sExpression.Replace("%i", i.ToString());
                                      EqCompiler oCompiler = new EqCompiler(sExpression, true);
                                      oCompiler.Compile();
                                      double dValue = oCompiler.Calculate();
                                      dValue = Math.Round(dValue, oP.DecimalPts);
  
                                      allLines[oP.LineNum - 1] = line.Substring(0, oP.ColumnNum - 1) + dValue.ToString() + line.Substring(oP.ColumnNum + oP.Length);
                                  }
                              }
                              count++;
                          }
                          //write new input file here
                          File.WriteAllLines(newInputFile, allLines);
                      }
                      catch (IOException ex)
                      {
                          MessageBox.Show(ex.ToString());
                      }
  
  
                      var process = new Process();
                      process.StartInfo = new ProcessStartInfo("swmm5.exe", newInputFile + " " + newRptFile);
                      process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                      process.Start();
                      process.WaitForExit();
  
                      Output output = new Output();
                      output.RunNumber = myIndex;
                      output.Index = s;
                      output.Values = new List&lt;double&gt;();
  
                      foreach(OutputValue oV in OutputValues) {
                           output.Values.Add(oV.getValue(newRptFile));
                      }
  
                      outputList.Add(output);
  
                      //get rid of files after run
                      File.Delete(newInputFile);
                      File.Delete(newRptFile);
  
                      myCount++;
                      ProgressBar.BeginInvoke(
                          new Action(() =&gt;
                              {
                                  ProgressBar.Value = myCount;
                              }
                      ));
                      ProgressLabel.BeginInvoke(
                          new Action(() =&gt;
                              {
                                  ProgressLabel.Text = String.Format("{0} / {1} Runs Completed", myCount, maxRuns);
                              }
                      ));
                  });
          });
      }
  </code></pre>