如果应用程序超过某个运行时,我想停止所有正在运行的任务。 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);
}