Exemplo n.º 1
0
        private async Task <Testcase> GetTestcaseAsync(int i, int serial)
        {
            Testcase testcase = new Testcase();

            if (isSample)
            {
                testcase.Serial    = samples[i].Serial;
                testcase.ProblemId = samples[i].ProblemId;
                testcase.In        = samples[i].In;
                testcase.Out       = samples[i].Out;
            }
            else
            {
                testcase = await HttpClientManager.ExecuteGetJsonAsync <Testcase>(string.Format(FIND_BY_PROBLEM_ID_TESTCASE, probrem.id, serial));

                if (testcase.In.Contains("(terminated because of the limitation)"))
                {
                    testcase.In = await HttpClientManager.ExecuteGetStringAsync(string.Format(FIND_BY_PROBLEM_ID_TESTCASE_ALT_IN, probrem.id, serial));
                }
                if (testcase.Out.Contains("(terminated because of the limitation)"))
                {
                    testcase.Out = await HttpClientManager.ExecuteGetStringAsync(string.Format(FIND_BY_PROBLEM_ID_TESTCASE_ALT_OUT, probrem.id, serial));
                }
            }
            return(testcase);
        }
Exemplo n.º 2
0
        private Result ExecTest(ProcessStartInfo startInfo, Testcase testcase)
        {
            var result  = new Result();
            var timeout = TimeSpan.FromSeconds(probrem.problemtimelimit * 4);

            bool     isTimedOut       = false;
            bool     isMemoryExceeded = false;
            bool     isError          = false;
            long     memory           = 0;
            TimeSpan time             = new TimeSpan();

            var    stdout = new StringBuilder();
            var    stderr = new StringBuilder();
            string text   = testcase.In.Replace("\n", "\r\n");

            //string[] text = testcase.In.Replace("\n", "\r\n").Split(new string[] { "\r\n" }, StringSplitOptions.None);
            using (Process process = Process.Start(startInfo))
            {
                process.OutputDataReceived += (ss, ee) => { if (ee.Data != null)
                                                            {
                                                                stdout.AppendLine(ee.Data);
                                                            }
                };                                                                                                  // 標準出力に書き込まれた文字列を取り出す
                process.ErrorDataReceived += (ss, ee) => { if (ee.Data != null)
                                                           {
                                                               stderr.AppendLine(ee.Data);
                                                           }
                };                                                                                                 // 標準エラー出力に書き込まれた文字列を取り出す
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
                //process.StandardInput.WriteLine(text); タイムアウトする処理の場合、受け側で読み込みが開始せず遅延するため、非同期処理に変更
                process.StandardInput.WriteLineAsync(text);
                DateTime startTime = DateTime.Now;

                do //プロセスが終了するまで監視
                {
                    try
                    {
                        process.Refresh();
                        time   = DateTime.Now - startTime;
                        memory = Math.Max(memory, process.PeakWorkingSet64);
                    }
                    catch (InvalidOperationException)
                    { } //プロセスが終了している場合、何もしない
                    catch (ArgumentException)
                    { } //プロセスが開かれていない場合も、何もしない

                    if (!string.IsNullOrEmpty(stderr.ToString()))
                    {
                        isError = true;
                        process.WaitForExit();
                    }

                    if (memory > probrem.problemmemorylimit * 1024)
                    {
                        isMemoryExceeded = true;
                    }
                    if (time.TotalMilliseconds > timeout.TotalMilliseconds)
                    {
                        isTimedOut = true;
                    }
                    if (isMemoryExceeded || isTimedOut)
                    {
                        try
                        {
                            process.Kill();
                            process.WaitForExit();
                        }
                        catch (Win32Exception)
                        { } //プロセスが終了中の場合、何もしない
                        catch (InvalidOperationException)
                        { } //プロセスが終了している場合、何もしない
                    }
                } while (!process.HasExited);

                process.WaitForExit();
                process.CancelOutputRead();
                process.CancelErrorRead();

                result.ProcessingTime = time;
                result.UsedMemory     = memory;
            }

            var resultString = stdout.ToString();

            result.Output = resultString;
            string res;

            if (isMemoryExceeded || isTimedOut)
            {
                if (isMemoryExceeded)
                {
                    res = "MLE";
                }
                else
                {
                    res = "TLE";
                }
            }
            else
            {
                if (isError)
                {
                    res           = "RE";
                    txtError.Text = stderr.ToString();
                }
                else
                {
                    if (resultString == testcase.Out.Replace("\n", "\r\n"))//改行の統一
                    {
                        res = "AC";
                    }
                    else
                    {
                        res = "WA";
                    }
                }
            }
            result.Status = res;
            return(result);
        }