public Task <dynamic> Execute() { lock (this) { if (currentState != ScriptUnitState.Ready) { Reset(); } if (currentState != ScriptUnitState.Ready) { throw new InvalidScriptUnitStateException(); } return(Task.Run <dynamic>(() => { try { lastLine = -1; lastError = null; currentState = ScriptUnitState.Running; PublishEvent(new ScriptUnitStateEvent(this, currentState)); if (isDebugEnabled) { engine.SetTrace(traceDelegate); //set again trace at beginning } foreach (var g in globals) { builtinModule.SetVariable(g.Key, g.Value); } var result = compiled.Execute(scope); currentState = ScriptUnitState.Done; PublishEvent(new ScriptUnitStateEvent(this, currentState)); return result; } catch (PythonScriptUnitAbortException ex) { //script was aborted through the abort exception currentState = ScriptUnitState.Aborted; lastError = null; throw ex; } catch (Exception ex) { currentState = ScriptUnitState.Error; lastError = ex; PublishEvent(new ScriptUnitStateEvent(this, currentState, ex)); throw ex; } })); } }
public PythonScriptUnit(PythonScript sourceScript, bool enableDebug = true, ScriptScope scriptScope = null) { this.name = sourceScript.Name; this.script = sourceScript; Dictionary <string, object> options = new Dictionary <string, object>(); isDebugEnabled = enableDebug; options["Debug"] = enableDebug; engine = Python.CreateEngine(options); //setup trace delegate traceDelegate = new IronPython.Runtime.Exceptions.TracebackDelegate(TraceCallback); if (enableDebug) { engine.SetTrace(traceDelegate); } if (scriptScope == null) { scope = engine.CreateScope(); } else { scope = scriptScope; } builtinModule = engine.GetBuiltinModule(); builtinModule.SetVariable("WaitAll", new Action <Task[]>((tasks) => Task.WaitAll(tasks))); builtinModule.SetVariable("TaskSleep", new Func <double, Task>((secs) => TaskSleep(secs))); builtinModule.SetVariable("StartLambda", new Func <Func <dynamic>, Task>((action) => Task.Run(action))); builtinModule.SetVariable("AllowBreak", new Action(() => AllowBreak())); builtinModule.SetVariable("Break", new Action(() => Break())); builtinModule.SetVariable("WaitBreak", new Action(() => { })); //empty method so the break will happen there source = engine.CreateScriptSourceFromString(script.Content, SourceCodeKind.File); try { compiled = source.Compile(); currentState = ScriptUnitState.Ready; PublishEvent(new ScriptUnitStateEvent(this, currentState)); } catch (SyntaxErrorException ex) { currentState = ScriptUnitState.Error; PublishEvent(new ScriptUnitStateEvent(this, currentState)); throw ex; } }
public void Reset() { lock (this) { if (IsBusy) { throw new InvalidScriptUnitStateException(); } if (compiled != null && script != null) { currentState = ScriptUnitState.Ready; } else { currentState = ScriptUnitState.Idle; } breakEvent.Reset(); requestBreakEvent.Reset(); PublishEvent(new ScriptUnitStateEvent(this, currentState)); } }
protected IronPython.Runtime.Exceptions.TracebackDelegate TraceCallback(IronPython.Runtime.Exceptions.TraceBackFrame frame, string eventName, object payload) { bool abort = false; abort = abortEvent.WaitOne(0); //test abort signal int currentFrameLine = (int)frame.f_lineno; if (currentFrameLine != lastLine) { lastLine = currentFrameLine; PublishEvent(new ScriptUnitProgressEvent(this, source != null ? source.MapLine(currentFrameLine) : currentFrameLine)); } if (!abort) { bool breaking = breakEvent.WaitOne(0); //test if a break was requested if (!breaking) { int currentLine = source != null?source.MapLine(currentFrameLine) : currentFrameLine; lock (breakpoints) { breaking |= breakpoints.Contains(currentLine); } } if (breaking) { currentState = ScriptUnitState.Breaking; PublishEvent(new ScriptUnitStateEvent(this, currentState)); //break! //wait for resume event (or abort as we could want to abort while debugging) int eventIndex = AutoResetEvent.WaitAny(new WaitHandle[] { resumeEvent, abortEvent }); if (eventIndex == 1) { abort = true; } else if (eventIndex == 0) { breaking = false; currentState = ScriptUnitState.Running; PublishEvent(new ScriptUnitStateEvent(this, currentState)); } } } if (abort) { breakEvent.Reset(); requestBreakEvent.Reset(); currentState = ScriptUnitState.Aborting; PublishEvent(new ScriptUnitStateEvent(this, currentState)); throw new PythonScriptUnitAbortException(); } return(traceDelegate); }
public ScriptUnitStateEvent(IScriptUnit unit, ScriptUnitState state, Exception error = null) { this.unit = unit; this.state = state; this.error = error; }