private static RunningResults RunDocker(DockerSandboxRunnerSettings settings, DirectoryInfo dir) { var name = Guid.NewGuid(); var dockerCommand = BuildDockerCommand(settings, dir, name); log.Info($"Start process command: docker {dockerCommand}"); using (var dockerShellProcess = BuildShellProcess(dockerCommand)) { var sw = Stopwatch.StartNew(); dockerShellProcess.Start(); var utf8StandardErrorReader = new StreamReader(dockerShellProcess.StandardError.BaseStream, Encoding.UTF8); var utf8StandardOutputReader = new StreamReader(dockerShellProcess.StandardOutput.BaseStream, Encoding.UTF8); var readErrTask = new AsyncReader(utf8StandardErrorReader, settings.OutputLimit).GetDataAsync(); var readOutTask = new AsyncReader(utf8StandardOutputReader, settings.OutputLimit).GetDataAsync(); var isFinished = Task.WaitAll(new Task[] { readErrTask, readOutTask }, (int)(settings.MaintenanceTimeLimit + settings.TestingTimeLimit).TotalMilliseconds); var ms = sw.ElapsedMilliseconds; RunningResults unsuccessfulResult = null; if (!dockerShellProcess.HasExited) { GracefullyShutdownDocker(dockerShellProcess, name, settings); } log.Info($"Docker написал в stderr: {readErrTask.Result}"); log.Info($"Docker написал в stdout: {readOutTask.Result}"); if (!isFinished) { log.Warn($"Не хватило времени ({ms} ms) на работу Docker в папке {dir.FullName}"); unsuccessfulResult = new RunningResults(Verdict.TimeLimit, (int)Math.Round(settings.TestingTimeLimit.TotalSeconds)); } else if (readErrTask.Result.Length > settings.OutputLimit || readOutTask.Result.Length > settings.OutputLimit) { log.Warn("Программа вывела слишком много"); unsuccessfulResult = new RunningResults(Verdict.OutputLimit); } else { log.Info($"Docker закончил работу за {ms} ms"); } if (unsuccessfulResult != null) { return(unsuccessfulResult); } if (dockerShellProcess.ExitCode != 0) { log.Warn($"Упал в папке {dir.FullName}"); return(new RunningResults(Verdict.SandboxError) { Logs = new[] { $"Exit code: {dockerShellProcess.ExitCode}", $"stdout: {readOutTask.Result}", $"stderr: {readErrTask.Result}" } }); } if (readOutTask.Result == "" && readErrTask.Result == "") // Поддержка старого соглашения { return new RunningResults(Verdict.Ok) { Logs = new[] { "Чеккер ничего не вывел" } } } ; return(ResultParser.Parse(readOutTask.Result, readErrTask.Result)); } }