How to stop engine execution after it has started

Aug 28, 2013 at 11:20 AM
Hi Paul,

This just happened to me now, one error in my script is generating an endless loop in the JScript code so the engine never stops executing.

Is there any method to stop engine execution? Of course generating and exception from one external (C#) function might work, but that would make me put code for that on almost every function.

Victor
Coordinator
Aug 28, 2013 at 9:30 PM
Presumably you want to terminate execution if the script takes too long? There's no functionality built into Jurassic. However, you can still do it.
  1. Spin up a thread.
  2. Execute the script on the new thread.
  3. On the original thread, use the Join method to wait for the thread to terminate.
  4. If a timeout occurs instead, call Abort on the thread to terminate script execution.
Aug 29, 2013 at 5:07 AM
Thanks, that should do the job.
Oct 14, 2013 at 3:10 PM
The downer with the suggested solution is that Microsoft and various experts recommend never using Thread.Abort. A good collection of links here.

Really a built-in interrupt capability is needed, or any host application becomes potentially unstable every time it executes an end-user script.
Coordinator
Oct 17, 2013 at 12:32 AM
True, although most of the reasons to avoid Thread.Abort don't apply in this case:
  1. The issues around corruption of state can be avoided by throwing away the ScriptEngine and all related objects (e.g. references to ObjectInstance objects).
  2. The issues around aborting code holding open locks, or getting stuck in a native blocking method that .NET can't terminate, are mostly mitigated by the lack of threading functionality in javascript and the fact that Jurassic uses .NET threading functionality (which is generally abort-aware).
That's not to say that using Thread.Abort to abort a script is 100% reliable; the link mentions a bug in .NET which could potentially still be an issue.

A built-in interrupt capability could be made 100% reliable, but would of course have it's own problems. Either you put a check at the start of every statement (bloating the generated code and likely killing performance) or you risk having code snippets that can't be aborted (tight infinite loops being especially problematic).
Oct 18, 2013 at 6:06 PM

Would running all javascript in its own appdomain, then tearing down that to abort work? Would require all jsobjects to be Marshalled though...

Coordinator
Oct 20, 2013 at 9:38 PM
Edited Oct 20, 2013 at 9:42 PM
Yes, running javascript in a separate AppDomain helps with isolation (mostly due to the fact that statics are initialized per app-domain). You don't need to marshal everything, just the inputs and outputs to the AppDomain. You can check out how I use AppDomains here: https://jurassic.codeplex.com/SourceControl/latest#Test Suite Core/Core/TestSuite.cs

(The discussion board doesn't handle URLs with spaces, so you'll need to copy and paste the URL)