|
I eventually came up with an interrupt execution approach that works for me however it is extremely crude and specific to the way I use the DLR. Despite that it's far better than the previous situation with the Thread.Abort approach leaking memory and threads.
The way I did it was to was to add a static event to the Interpreter class in the Microsoft.Scripting class to notify my application everytime a new interpreter class is created. In my app I then keep a track of the Interpreter instances that belong to a
certain thread - my app only ever runs one DLR instance at a time per thread - and when its time to interrupt the execution of a running script the application sets the _halt Execution boolean for all the Interpreter instances on that thread.
The relevant code is shown below on the off chance anyone else happens to have the same usage mode and interrupt execution requirement. The proper design would be to manage the interruption through the Scope or ScriptScope object but that was beyond
me.
public delegate
void InterpreterCreatedDelegate(Interpreter interpreter);
public
class Interpreter {
...
private
bool m_haltExecution;
public
string ThreadName;
public
static event InterpreterCreatedDelegate InterpreterCreated;
internal Interpreter(LambdaExpression lambda,
bool[] localIsBoxed, int maxStackDepth,
Instruction[] instructions, ExceptionHandler[] handlers, DebugInfo[] debugInfos) {
...
ThreadName = Thread.CurrentThread.Name;
if (InterpreterCreated != null) {
InterpreterCreated(this);
}
}
internal
void RunInstructions(InterpretedFrame frame, int endInstruction) {
var instructions = _instructions;
int index = frame.InstructionIndex;
while (index < endInstruction) {
index += instructions[index].Run(frame);
frame.InstructionIndex = index;
if (m_haltExecution) {
throw new ApplicationException("Script was halted by external intervention.");
}
}
}
private
void RunInstructions(InterpretedFrame frame) {
var instructions = _instructions;
int index = frame.InstructionIndex;
while (index < instructions.Length) {
index += instructions[index].Run(frame);
frame.InstructionIndex = index;
if (m_haltExecution) {
throw new ApplicationException("Script was halted by external intervention.");
}
}
}
public
void Halt() {
m_haltExecution =
true;
}
public
void Reset() {
m_haltExecution =
false;
}
Regards,
Aaron
|