/// <summary> /// 带超时执行任务 /// </summary> /// <param name="things">需要执行的任务</param> /// <param name="timeoutMilliseconds">超时时间微秒</param> /// <param name="timeoutHandler">如果超时执行的操作</param> /// <param name="isForceKill">超时后是否强制abort线程</param> /// <returns></returns> public static string CallWithTimeout(ReturnStringTaskHandler things, int timeoutMilliseconds, Action timeoutHandler = null, bool isForceKill = false) { string ret = null; Thread threadToKill = null; Action wrappedAction = () => { threadToKill = Thread.CurrentThread; ret = things.Invoke(); }; IAsyncResult result = wrappedAction.BeginInvoke(null, null); if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds)) { wrappedAction.EndInvoke(result); } else { if (timeoutHandler != null) { timeoutHandler.Invoke(); } if (isForceKill) { threadToKill.Abort(); } throw new TimeoutException(); } return(ret); }
public ExecStatus JudgeProgeam(string input, string output) { Process p = null; ExecStatus ret = ExecStatus.TIMEOUT; ReturnStringTaskHandler rsth = new ReturnStringTaskHandler( () => { string result_tmp = null; p = new Process(); p.StartInfo.WorkingDirectory = workPath; p.StartInfo.FileName = generatedEXEPath; p.StartInfo.UseShellExecute = false; if (input != null) { p.StartInfo.RedirectStandardInput = true; } p.StartInfo.RedirectStandardOutput = true; p.StartInfo.CreateNoWindow = true; p.Start(); if (p.HasExited) { return(result_tmp); } if (input != null) { p.StandardInput.AutoFlush = true; p.StandardInput.WriteLine(input); p.StandardInput.Flush(); } p.WaitForExit(); result_tmp = p.StandardOutput.ReadToEnd(); Console.WriteLine("excute output: " + p.StandardOutput.ReadToEnd()); Console.WriteLine("excute ExitCode: " + p.ExitCode); return(result_tmp); } ); try { this.result = Timeout.CallWithTimeout(rsth, 3000, delegate() { p.Kill(); }, false); } catch (TimeoutException e) { Console.WriteLine("捕获超时异常: " + e.Message); ret = ExecStatus.TIMEOUT; } finally { if (!p.HasExited) { p.Close(); } if (File.Exists(generatedEXEPath)) { File.Delete(generatedEXEPath); } } if (this.result != null) { if (!this.result.Equals(output)) { ret = ExecStatus.WRONG; } else { ret = ExecStatus.ACCEPT; } } return(ret); }