public void KillOnJobClose_ShouldKillProcessOnClose() { using (var job = new JobObject()) { job.SetLimits(new JobObjectLimits() { Flags = JobObjectLimitFlags.DieOnUnhandledException | JobObjectLimitFlags.KillOnJobClose, }); var psi = new ProcessStartInfo { FileName = "ping", Arguments = "127.0.0.1 -n 100", UseShellExecute = true, CreateNoWindow = true, }; using (var process = Process.Start(psi)) { Assert.False(process.WaitForExit(500)); // Ensure process is started job.AssignProcess(process); job.Close(); process.WaitForExit(); } } }
public ProcessExecutionInfo Start(int timeLimit, int memoryLimit) { var executionInfo = new ProcessExecutionInfo(); using (var job = new JobObject()) { // Prepare job job.SetExtendedLimitInformation(PrepareJobObject.GetExtendedLimitInformation(timeLimit, memoryLimit)); job.SetBasicUiRestrictions(PrepareJobObject.GetUiRestrictions()); // Start process and assign it to job object this.process.Start(); var memoryTaskCancellationToken = new CancellationTokenSource(); var memoryTask = Task.Run( () => { while (true) { // ReSharper disable once AccessToDisposedClosure var peakWorkingSetSize = this.PeakWorkingSetSize; executionInfo.MaxMemoryUsed = Math.Max(executionInfo.MaxMemoryUsed, peakWorkingSetSize); if (memoryTaskCancellationToken.IsCancellationRequested) { return; } Thread.Sleep(30); } }, memoryTaskCancellationToken.Token); job.AddProcess(this.process.Handle); this.process.PriorityClass = ProcessPriorityClass.RealTime; // Process input if (this.charsToWrite != null) { try { this.process.StandardInput.WriteAsync(this.charsToWrite, 0, this.charsToWrite.Length) .ContinueWith( delegate { // this.process.StandardInput.AutoFlush = false; this.process.StandardInput.FlushAsync(); }); } catch (IOException) { // The pipe has been ended exception (when process is stopped before the write is done) } } var exited = this.process.WaitForExit(timeLimit); if (!exited) { // TODO: Fix: Console.WriteLine(job.GetExtendedLimitInformation().BasicLimitInformation.ActiveProcessLimit); job.Close(); executionInfo.ProcessKilledBecauseOfTimeLimit = true; // Time limit } // Process output var output = this.process.StandardOutput.ReadToEnd(); // Process error var errorOutput = this.process.StandardError.ReadToEnd(); memoryTaskCancellationToken.Cancel(); memoryTask.Wait(30); // To be sure that memory consumption will be evaluated correctly // Prepare execution info executionInfo.StandardOutputContent = output; executionInfo.StandardErrorContent = errorOutput; } return(executionInfo); }