/// <summary> /// Creates a cancellable task that runs SAPS on the given instance. /// </summary> /// <param name="instance">Instance to run on.</param> /// <param name="cancellationToken">Token that is regularly checked for cancellation. /// If cancellation is detected, the task will be stopped.</param> /// <returns>A task that has returns the run's runtime on completion.</returns> public Task <RuntimeResult> Run(InstanceSeedFile instance, CancellationToken cancellationToken) { // Define process to start SAPS. var processInfo = this.BuildProcessStartInfo(instance); return(Task.Run( function: () => { // Start process. using var process = Process.Start(processInfo); // Process needs to be canceled if cancellation token is canceled. var processRegistration = cancellationToken.Register( () => ProcessUtils.CancelProcess(process)); // Wait until end of process. process.WaitForExit(); // If the process was cancelled, clean up resources and escalate it up. if (cancellationToken.IsCancellationRequested) { SapsRunner.CleanUp(process, processRegistration); cancellationToken.ThrowIfCancellationRequested(); } // If the process was not cancelled, first check the output for CPU time. var output = process.StandardOutput.ReadToEnd(); // Then clean up resources. SapsRunner.CleanUp(process, processRegistration); return SapsRunner.CreateRuntimeResult(output, this._timeout); }, cancellationToken: cancellationToken)); }
public void CancelProcessWorksOnExitedProcess() { // Cancel once. ProcessUtils.CancelProcess(this._process); Assert.True(this._process.HasExited); // Cancel twice - no exception should be thrown. ProcessUtils.CancelProcess(this._process); }
/// <summary> /// Creates a cancellable task that runs a target algorithm on the given instance. /// </summary> /// <param name="instance">Instance to run on.</param> /// <param name="cancellationToken">Token that is regularly checked for cancellation. /// If cancellation is detected, the task will be stopped.</param> /// <returns>A task that returns statistics about the run on completion.</returns> public Task <TResult> Run(InstanceSeedFile instance, CancellationToken cancellationToken) { // Define process to target algorithm from command line. var processInfo = this.BuildProcessStartInfo(instance); // Make sure output and Error stores are clean. this.Output.Clear(); this.Error.Clear(); return(Task.Run( function: () => { // Start process and make sure it's cancelled if the cancellationToken is cancelled. using (var process = Process.Start(processInfo)) using (var processRegistration = cancellationToken.Register(() => ProcessUtils.CancelProcess(process))) { LoggingHelper.WriteLine(VerbosityLevel.Trace, "Started process."); // Catch all output. // Read streams asynchronously to prevent deadlocks. process.OutputDataReceived += (s, e) => this.Output.AppendLine(e.Data); process.ErrorDataReceived += (s, e) => this.Error.AppendLine(e.Data); process.BeginOutputReadLine(); process.BeginErrorReadLine(); // Wait until end of process. process.WaitForExit(); if (cancellationToken.IsCancellationRequested) { this.HandleCancellation(process, cancellationToken); } // Parse result. OriginalRunResult originalRunResult; try { originalRunResult = this.ExtractRunResult(); } catch (Exception) { // Write information to file if anything goes wrong. this.WriteProcessOutputToFiles(process); throw; } var result = this.CreateRunResult(originalRunResult); LoggingHelper.WriteLine(VerbosityLevel.Debug, $"Result: {result}"); return result; } }, cancellationToken: cancellationToken)); }
/// <summary> /// Creates a cancellable task that runs the <see cref="CommandExecutorBase{TResult}.Command"/> on the given instance. /// </summary> /// <param name="instance">Instance to run on.</param> /// <param name="cancellationToken">Token that is regurlarly checked for cancellation. /// If cancellation is detected, the task will be stopped.</param> /// <returns>A task that returns the run's result on completion.</returns> public override Task <ContinuousResult> Run(InstanceFile instance, CancellationToken cancellationToken) { // Define process and redirect standard output to read value to optimize from output. var processInfo = this.BuildProcessStartInfo(instance); processInfo.RedirectStandardOutput = true; return(Task.Run( function: () => { // Start process. var timer = new Stopwatch(); timer.Start(); using (var process = Process.Start(processInfo)) using (var processRegistration = cancellationToken.Register(() => ProcessUtils.CancelProcess(process))) { // Wait until end of process. process.WaitForExit(); // If the process was cancelled, clean up resources and escalate it up. if (cancellationToken.IsCancellationRequested) { this.CleanUp(process); cancellationToken.ThrowIfCancellationRequested(); } // If the process has inappropriate exit code, clean up resources and return cancelled result. if (process.ExitCode != 0) { this.CleanUp(process); return ContinuousResult.CreateCancelledResult(this._timeout); } // If the process was not cancelled, find the last value written to console. string output = process.StandardOutput.ReadToEnd(); timer.Stop(); // If the output does not match to regex, clean up resources and return cancelled result. if (!ValueReadingExecutor.NumberMatcher.IsMatch(output)) { this.CleanUp(process); return ContinuousResult.CreateCancelledResult(this._timeout); } // If the output matches to regex, clean up resources and return the founded output as result. double value = double.Parse(ValueReadingExecutor.NumberMatcher.Match(output).Value, CultureInfo.InvariantCulture); this.CleanUp(process); return new ContinuousResult(value, timer.Elapsed); } }, cancellationToken: cancellationToken)); }
/// <summary> /// Creates a cancellable task that runs the algorithm on the given instance. /// </summary> /// <param name="instance">Instance to run on.</param> /// <param name="cancellationToken">Token that should regurlarly be checked for cancellation. /// If cancellation is detected, the task has to be stopped.</param> /// <returns> /// A task that returns everything important about the run on completion. /// </returns> public Task <ContinuousResult> Run(InstanceFile instance, CancellationToken cancellationToken) { // Define process to start BBOB. var processInfo = this.BuildProcessStartInfo(instance); return(Task.Run( function: () => { // Start process. var timer = new Stopwatch(); timer.Start(); using var process = Process.Start(processInfo); // Process needs to be canceled if cancellation token is canceled. var processRegistration = cancellationToken.Register( () => ProcessUtils.CancelProcess(process)); // Wait until end of process. process.WaitForExit(); // If the process was cancelled, clean up resources and escalate it up. if (cancellationToken.IsCancellationRequested) { this.CleanUp(process, processRegistration); cancellationToken.ThrowIfCancellationRequested(); } // If the process was not cancelled, first check the console output for result. var output = process.StandardOutput.ReadToEnd(); timer.Stop(); var functionValue = BbobRunner.ExtractFunctionValue(output); // Then clean up resources. this.CleanUp(process, processRegistration); // Finally return the result. return new ContinuousResult(functionValue, timer.Elapsed); }, cancellationToken: cancellationToken)); }
/// <summary> /// Creates a cancellable task that runs the <see cref="CommandExecutorBase{TResult}.Command"/> on the given instance. /// </summary> /// <param name="instance">Instance to run on.</param> /// <param name="cancellationToken">Token that is regurlarly checked for cancellation. /// If cancellation is detected, the task will be stopped.</param> /// <returns>A task that returns the run's runtime on completion.</returns> public override Task <RuntimeResult> Run(InstanceFile instance, CancellationToken cancellationToken) { // Define process to target algorithm from command line. var processInfo = this.BuildProcessStartInfo(instance); return(Task.Run( function: () => { var timer = new Stopwatch(); timer.Start(); // Start process and make sure it's cancelled if the cancellationToken is cancelled. using (var process = Process.Start(processInfo)) using (var processRegistration = cancellationToken.Register(() => ProcessUtils.CancelProcess(process))) { // Wait until end of process. process.WaitForExit(); // If the process was cancelled, escalate it up. if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } // If the process has inappropriate exit code, clean up resources and return cancelled result. if (process.ExitCode != 0) { return RuntimeResult.CreateCancelledResult(this._timeout); } // If the process was not cancelled, return CPU time as result. timer.Stop(); return new RuntimeResult(timer.Elapsed); } }, cancellationToken: cancellationToken)); }
public void CancelProcessCancelsProcess() { ProcessUtils.CancelProcess(this._process); Assert.True(this._process.HasExited); }
public void CancelProcessThrowsOnDisposedProcess() { this._process.Dispose(); Assert.Throws <InvalidOperationException>(() => ProcessUtils.CancelProcess(this._process)); }