2014-01-14 13 views
5

私がする必要があるのは、非同期を実行しているタスクをキャンセルできることです。ボタンから非同期タスクをキャンセルする

私は検索しており、私の頭の中を包んでいるように見えません。私はちょうどそれが私の現在のセットアップに実装される方法を識別するように見える。

私の仕事は私の仕事です。取り消しトークンを実装する場所や方法についての助けがあれば、大歓迎です。

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

私は手渡すコードはありませんが、キャンセルソースを作成し、キャンセルトークンを作成し、あなたのStartTask(IProgress の隣)にあなたのUIのソースからトークンを取り消し、非同期メソッドでIsCancelledをチェックします。 – Liath

+0

MSDNには例があります。http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx – garf1eld

答えて

10

取り消しをサポートするための最良の方法は、async方法にCancellationTokenを渡すことです。ボタンを押すと、トークンをキャンセルすることができます。

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(); 
    } 
} 

これでは十分ではありません。 startThreadStartProcessの両方の方法は、CancellationTokenがキャンセルされて登録された後、協力してタスクをキャンセルするように更新する必要があります。

+0

良い答えですが、OPのように苦労している人もいます"協調的に取り消す"という意味のより良い定義/例。 –

+0

ジャレッドとスコットに感謝します。私は自分の状況がちょうど仕事をキャンセルするよりも少し一般的ではないことを理解しています。私は、私が生まれたプロセスを殺し、その仕事を終了する必要があることを理解しています。私は同様の状況にオンラインで参照を見つけることができないので、単に失われています。 –

関連する問題