2014-01-14 4 views
5

Что мне нужно сделать, так это отменить задачу, выполняющую async.Отменить задачу Async от кнопки

Я искал и не могу обернуть вокруг себя голову. Я просто не могу понять, как это будет реализовано в моей текущей настройке.

Вот мой код, который отключает мою задачу. Любая помощь о том, где и как реализовать токен отмены, будет с благодарностью оценена.

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 => 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(() => 
     { 
      int myCount = 0; 
      int maxRuns = index.Count(); 
      List<string> myStrings = index; 
      Parallel.ForEach(myStrings, 
       new ParallelOptions() 
       { 
        MaxDegreeOfParallelism = settings.ConcurrentRuns 
       }, (s) => 
       { 
        //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<double>(); 

        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(() => 
          { 
           ProgressBar.Value = myCount; 
          } 
        )); 
        ProgressLabel.BeginInvoke(
         new Action(() => 
          { 
           ProgressLabel.Text = String.Format("{0}/{1} Runs Completed", myCount, maxRuns); 
          } 
        )); 
       }); 
     }); 
    } 
+0

У меня нет кода под рукой, но IIRC вам нужно создать cancellationsource, создать аннулирование маркер и передать в ваш StartTask (рядом с IProgress ), вы затем отменяете токен через источник в пользовательском интерфейсе и проверяете IsCancelled в вашем асинхронном методе. – Liath

+0

У MSDN есть пример http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx – garf1eld

ответ

10

Лучший способ поддержать отмену, чтобы передать CancellationToken методу async. Нажатие кнопки затем может быть привязано к отмене токена

class TheClass 
{ 
    CancellationTokenSource m_source; 

    void StartThread() { 
    m_source = new CancellationTokenSource; 
    StartThread(m_source.Token); 
    } 

    private async void StartThread(CancellationToken token) { 
    ... 
    } 

    private void OnCancelClicked(object sender, EventArgs e) { 
    m_source.Cancel(); 
    } 
} 

Этого еще недостаточно. Оба startThread и StartProcess методы должны быть обновлены, чтобы совместно отменить задание как только CancellationToken регистры как отменили

+0

Хороший ответ, но с кем-то, кто борется столько же, сколько с OP, это может быть приятно дать лучшее определение/пример того, что означает «Кооперативно отменить». –

+0

Спасибо, Джаред, а также Скотт. Я понимаю, что моя ситуация немного реже, чем просто отменить задачу. Я понимаю, что мне нужно убить процесс, который я породил, и завершить задачу. Я просто потерялся, так как я не могу найти ссылку в аналогичной ситуации. –