I am using a .Net JavaScript implementation called Jurassic to run user-controlled scripts within my .Net 4 WPF application coded in VB.Net - C# answers are fine. The script engine runs on its own thread and provides an API for the script to interact with my application. This all works really nicely until a user executes a script that causes an infinite loop and takes out a core of the processor.
The method that runs within the thread looks something like this but with more irrelevant bits:
Sub run()
Do While True
Try
Do Until queue.Count = 0
Dim functionName As String = queue(queue.Count - 1)
queue.RemoveAt(queue.Count - 1)
scriptEngine.CallGlobalFunction(functionName)
Loop
thread.Sleep(Timeout.Infinite)
Catch ex As ThreadInterruptedException
' Wake and loop
Catch ex As Exception
' Log
End Try
Loop
End Sub
I have a monitoring class on another thread in place that detects script engine threads that are using a lot of resources by taking note of when they wake and sleep and flagging up any that run for too long.
Once a thread has been flagged up by the monitoring class I'm a bit stuck. Currently I explain the situation to the user and give them the option of terminating the thread. I do this using Thread.Abort(). However I would much rather allow the thread to keep running but somehow prevent it from using so much processor time.
The problem here is that I cannot run any code on the thread once it is in this state as the infinite loop is occurring within CallGlobalFunction() method within the Jurassic code, so I cannot just add a Thread.Yield() into the loop. I have briefly considered hacking my way through the Jurassic code to see if there is any way I can but that would be very tough and quite possibly impossible.
The only ways I have been able to interact with the thread so far are using Thread.Abort() as stated above and the deprecated Thread.Suspend().
So is there any way to yield a thread while it is executing a method or am I just going to have to kill it?
Thanks for any help and I hope this makes sense,
Sam.
Extra Info:
The reason I care about keeping the thread alive is because the user who wrote the script and the user who is running it may not be the same, and I want to keep the experience as smooth as possible the the user running the thread. There also might be legitimate situations in which a single JavaScript function would run for a long time and I do not want to kill that, I just want to stop being allowed to hog the resources.
Solutions that involve stopping the thread from slowing down the system but that still show high CPU usage are not preferable because I do not want the user to wrongly feel that the application is resource intensive.