从按钮取消异步任务 [英] Cancel Async Task from a button

查看:306
本文介绍了从按钮取消异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做的是能够取消运行异步任务是什么。

我一直在寻找,似乎无法环绕它我的头。我只是不能似乎辨别将如何落实到我的当前设置。

下面是我的code,它激发我的任务了。在哪里或如何实施取消标记任何帮助将大大AP preciated。

 专用异步无效startThread()
    {
        //开始前做UI的东西
        ProgressLabel.Text =的String.Format(0 / {0}完成奔流,index.Count());
        ProgressBar.Maximum = index.Count();        等待ExecuteProcesses();        //排序的输出线列表
        outputList = outputList.OrderBy(O => o.RunNumber).ToList();        的foreach(在outputList输出O)
        {
            串outStr = o.RunNumber +,+ o.Index;
            的foreach(双OV在o.Values​​)
            {
                outStr + =的String.Format({0},OV);
            }            outputStrings.Add(outStr);
        }        字符串[] = csvOut outputStrings.ToArray();        File.WriteAllLines(settings.OutputFile,csvOut);
        //完成后做UI的东西。        ProgressLabel.Text = index.Count()+奔跑完成输出写入文件test.csv。
    }    私人异步任务ExecuteProcesses()
    {
        等待Task.Factory.StartNew(()=>
        {
            INT mycount的= 0;
            INT maxRuns = index.Count();
            清单<串GT; myStrings =指数;
            Parallel.ForEach(myStrings,
                新ParallelOptions()
                {
                    MaxDegreeOfParallelism = settings.ConcurrentRuns
                },(S)=>
                {
                    //这条线就是我们的目标运行计数。
                    INT myIndex = myStrings.IndexOf(多个)+ 1;                    串newInputFile = Path.Combine(settings.ProjectPath +文件/,Path.GetFileNameWithoutExtension(settings.InputFile)+ S +.INP,。);
                    串newRptFile = Path.Combine(settings.ProjectPath +文件/,Path.GetFileNameWithoutExtension(settings.InputFile)+ S +的.rpt,。);                    尝试
                    {
                        //负载的输入文件的内容
                        字符串[] = allLines File.ReadAllLines(Path.Combine(settings.ProjectPath,settings.InputFile));
                        字符串[] = indexSplit s.Split('。');                        这里//改变参数
                        诠释计数= 0;
                        的foreach(OptiFile的文件)
                        {
                            INT I = Int32.Parse(indexSplit [计数]);
                            的foreach(OptiParam oP处的oF.Parameters)
                            {
                                串线= allLines [oP.LineNum - 1];
                                如果(oP.DecimalPts == 0)
                                {
                                    字符串SEX pression = oP.Value;
                                    SEX pression =性爱pression.Replace(%i的,i.ToString());
                                    EqCompiler oCompiler =新EqCompiler(SEX pression,真正的);
                                    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);
                                }
                                其他
                                {
                                    字符串SEX pression = oP.Value;
                                    SEX pression =性爱pression.Replace(%i的,i.ToString());
                                    EqCompiler oCompiler =新EqCompiler(SEX pression,真正的);
                                    oCompiler.Compile();
                                    双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);
                                }
                            }
                            算上++;
                        }
                        //这里写新的输入文件
                        File.WriteAllLines(newInputFile,allLines);
                    }
                    赶上(IOException异常前)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                    VAR工艺=新工艺();
                    process.StartInfo =新的ProcessStartInfo(swmm5.exe,newInputFile ++ newRptFile);
                    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    的Process.Start();
                    process.WaitForExit();                    输出输出=新的输出();
                    output.RunNumber = myIndex;
                    output.Index =秒;
                    output.Values​​ =新的List<双>();                    的foreach(OutputValue OV在OutputValues​​){
                         output.Values​​.Add(oV.getValue(newRptFile));
                    }                    outputList.Add(输出);                    //运行后摆脱文件
                    File.Delete(newInputFile);
                    File.Delete(newRptFile);                    mycount的++;
                    ProgressBar.BeginInvoke(
                        新的Action(()=>
                            {
                                ProgressBar.Value = mycount的;
                            }
                    ));
                    ProgressLabel.BeginInvoke(
                        新的Action(()=>
                            {
                                ProgressLabel.Text =的String.Format({0} / {1}奔流完成,mycount的,maxRuns);
                            }
                    ));
                });
        });
    }


解决方案

要支持取消的最好方法是通过一个的CancellationToken 异步方法。然后,按钮preSS可绑取消标记

 类theClass描述
{
  CancellationTokenSource m_source;  无效StartThread(){
    m_source =新CancellationTokenSource;
    StartThread(m_source.Token);
  }  私人异步无效StartThread(令牌的CancellationToken){
    ...
  }  私人无效OnCancelClicked(对象发件人,EventArgs的发送){
    m_source.Cancel();
  }
}

这是不是很够,但。无论是 startThread StartProcess 方法都需要进行更新,以共同取消该任务一旦的CancellationToken 注册为取消

What I need to do is be able to cancel a task that is running async.

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.

Here is my code that fires my task off. Any help on where or how to implement a cancellation token would be greatly appreciated.

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

解决方案

The best way to support cancellation is to pass a CancellationToken to the async method. The button press can then be tied to cancelling the token

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

This isn't quite enough though. Both the startThread and StartProcess methods will need to be updated to cooperatively cancel the task once the CancellationToken registers as cancelled

这篇关于从按钮取消异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆