Beispiel #1
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);
        }