如果应用程序运行长于x,则取消所有任务

时间:2017-07-25 10:20:23

标签: c# .net c#-4.0 task task-parallel-library

如果应用程序超过某个运行时,我想停止所有正在运行的任务。 tokenSource.cancel()正在设置,但任务仍在运行,直到它们正常结束。猜测这是由于启动了一个在cmd /可执行文件中运行批处理的进程。我是否需要杀死这个过程,我可以用tpl完成它,还是一个完全不同的路线有益? 我读到了关于thread.abort()但它似乎不太受欢迎。

我从主窗口启动后台工作程序,执行ExecuteDefault。

Background worker = new BackgroundWorker();
worker.doWork += (o, ea) =>
{ ExecuteDefault(worker, tokenSource);};

在execute Default I中,从OSObject访问execute函数。所有必要的任务都将在此功能中启动。现在,如果应用程序运行时间超过350000ms,我想取消所有任务。

private void ExecuteDefault(Backgroundworker worker, CancellationTokenSource tokenSource)
{
... random stuff
OSObject.RunSystemCommands(outputPath, execPath, timeframe, tasks, worker, tokenSource);
... random stuff
Task.WaitAll(tasks.ToArray(), 350000);
tokenSource.Cancel();
}

在这里,我开始了不同的流程。正在执行像\ C logicaldisk这样的批处理执行或者像handle.exe这样的exe文件。

aublic static void RunSystemCommands(string outputPath, string execPath, int timeframe, List<Task> tasks, Backgroundowrker worker, CancellationTokenSource tokenSource)
{
    foreach(Command activeCommand in Commands.SystemCommands)
    {
        string keyname = activeCommmand.Name;
        if (keyname == "foo")
        {
        Task newTask = Task.Factory.Startnew(() =>
           {
           Executes.ExecuteBatch(outputFile, activeCommand)
           }, tokenSource.Token);
         tasks.Add(newTask);
        }
        else if (keyname == "bar")
        {
        ...
        }
    }
}

这是批处理命令的执行方式。

 public static void ExecuteBatch(string outputFile, Command command, bool parse = false)
    {
        log.DebugFormat("Executing Task: {0} | Name: {1} | Command: {2}", Task.CurrentId, command.Name, command.Execute);
        log.Info("Executing Task: " + command.Name);
        //create new process and write process start information
        Process p = new Process();

        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        startInfo.UseShellExecute = false;
        startInfo.FileName = @"C:\Windows\System32\cmd.exe";
        startInfo.StandardOutputEncoding = Encoding.GetEncoding(850);
        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardError = true;
        startInfo.CreateNoWindow = true;
        startInfo.Arguments = command.Execute;
        p.StartInfo = startInfo;

        string delimiter = new String('=', 80);
        string output = "";
        string errorOutput = "";

        log.DebugFormat("Task {0}: writing outputFile for {1}", Task.CurrentId, outputFile);
        System.IO.File.WriteAllText(outputFile, (command.Execute.Replace("/C ", "") + Environment.NewLine));
        System.IO.File.AppendAllText(outputFile, delimiter + Environment.NewLine + Environment.NewLine);


        p.ErrorDataReceived += (sender, eventArgs) => {
            errorOutput = "###Erroroutput### "+ eventArgs.Data + Environment.NewLine;

            System.IO.File.AppendAllText(outputFile, errorOutput);

        };

        p.OutputDataReceived += (sender, args) =>
        {
            if (args==null || args.Data==null || args.Data == "")
                return;

            output =args.Data+Environment.NewLine;

            if (parse == true)
            {
                output = Parser.ParseOutput(command.Name, output);
            }

            try
            {
                System.IO.File.AppendAllText(outputFile, output);
            }
            catch (Exception e)
            {

                log.Debug("Could not write to file. " + e.Message);
            }

        };

        p.Start();
        p.BeginOutputReadLine();

        p.WaitForExit(command.Timeout)

        log.DebugFormat("Task: {3} | Name: {4} | Start: {0}, End: {1}, Elapsed: {2}", p.StartTime.ToString("HH:mm:ss.fff"), DateTime.Now.ToString("HH:mm:ss.fff"), (DateTime.Now.Subtract(p.StartTime)).TotalMilliseconds, Task.CurrentId, command.Name);
    }

0 个答案:

没有答案