Example #1
0
        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();
                }
            }
        }
Example #2
0
        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);
        }