/// <summary> /// Invokes the parser using a separate thread. /// </summary> /// <remarks> /// Uses the <see cref="ParserWorkitem"/> helper class to execute parsing. This /// ensures that parser invocations always return, even if the parser itself hangs. /// </remarks> /// <param name="rd">A <see cref="System.IO.TextReader"/> with the code to parse.</param> /// <param name="filename">The filename or the value of <see cref="CODE"/> constant.</param> /// <param name="errors">The error list returned by the parser.</param> /// <returns></returns> static CompilationUnitNode InvokeParse(TextReader rd, string filename, out List <Parser.Error> errors) { errors = null; EventWaitHandle wait = new EventWaitHandle(false, EventResetMode.AutoReset); ParserWorkitem workitem = new ParserWorkitem(rd, filename, wait); Thread workerThread = new Thread(workitem.Parse); workerThread.Priority = ThreadPriority.AboveNormal; workerThread.Start(); if (wait.WaitOne(_timeout, false)) { // Were there any exceptions in parser itself? If so, rethrow these. if (workitem.ExceptionFromParser != null) { throw workitem.ExceptionFromParser; } // Parser finished regularly. -> Return results. errors = workitem.Errors; return(workitem.Result); } // If we arrive here, the timeout has elapsed -> // abort parser thread, then throw TimeoutException. // ************************************************* workerThread.Abort(); workerThread.Join(); // waits until the thread really is canceled throw new TimeoutException("Parser invocation timed out, timeout value (in ms): " + _timeout + "."); }
/// <summary> /// Invokes the parser using a separate thread. /// </summary> /// <remarks> /// Uses the <see cref="ParserWorkitem"/> helper class to execute parsing. This /// ensures that parser invocations always return, even if the parser itself hangs. /// </remarks> /// <param name="rd">A <see cref="System.IO.TextReader"/> with the code to parse.</param> /// <param name="filename">The filename or the value of <see cref="CODE"/> constant.</param> /// <param name="errors">The error list returned by the parser.</param> /// <returns></returns> static CompilationUnitNode InvokeParse(TextReader rd, string filename, out List<Parser.Error> errors) { errors = null; EventWaitHandle wait = new EventWaitHandle(false, EventResetMode.AutoReset); ParserWorkitem workitem = new ParserWorkitem(rd, filename, wait); Thread workerThread = new Thread(workitem.Parse); workerThread.Priority = ThreadPriority.AboveNormal; workerThread.Start(); if (wait.WaitOne(_timeout, false)) { // Were there any exceptions in parser itself? If so, rethrow these. if (workitem.ExceptionFromParser != null) throw workitem.ExceptionFromParser; // Parser finished regularly. -> Return results. errors = workitem.Errors; return workitem.Result; } // If we arrive here, the timeout has elapsed -> // abort parser thread, then throw TimeoutException. // ************************************************* workerThread.Abort(); workerThread.Join(); // waits until the thread really is canceled throw new TimeoutException("Parser invocation timed out, timeout value (in ms): " + _timeout + "."); }