Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding IronPython in a WinForms app and interrupting execution

BACKGROUND

  • I've successfully embedded IronPython in my WinForm apps using techniques like the one described here: http://blog.peterlesliemorris.com/archive/2010/05/19/embedding-ironpython-into-a-c-application.aspx
  • In the context of the embedding, my user may any write loops, etc.
  • I'm using the IronPython 2.6 (the IronPython for .NET 2.0 and IronPython for .NET 4.0)

MY PROBLEM

  • The users will need to interrupt the execution of their code
  • In other words they need something like the ability to hit CTRL-C to halt execution when running Python or IronPython from the cmdline
  • I want to add a button to the winform that when pressed halts the execution, but I'm not sure how to do this.

MY QUESTION

  • How can I make it to that pressing the a "stop" button will actually halt the execution of the using entered IronPython code?

NOTES

  • Note: I don't wish to simply throw away that "session" - I still want the user to be able to interact with session and access any results that were available before it was halted.
  • I am assuming I will need to execute this in a separate thread, any guidance or sample code in doing this correctly will be appreciated.
like image 749
namenlos Avatar asked May 27 '10 16:05

namenlos


1 Answers

This is basically an adaptation of how the IronPython console handles Ctrl-C. If you want to check the source, it's in BasicConsole and CommandLine.Run.

First, start up the IronPython engine on a separate thread (as you assumed). When you go to run the user's code, wrap it in a try ... catch(ThreadAbortException) block:

var engine = Python.CreateEngine();
bool aborted = false;
try {
    engine.Execute(/* whatever */);
} catch(ThreadAbortException tae) {
    if(tae.ExceptionState is Microsoft.Scripting.KeyboardInterruptException) {
        Thread.ResetAbort();
        aborted = true;
    } else { throw; }
}

if(aborted) {
    // this is application-specific
}

Now, you'll need to keep a reference to the IronPython thread handy. Create a button handler on your form, and call Thread.Abort().

public void StopButton_OnClick(object sender, EventArgs e) {
    pythonThread.Abort(new Microsoft.Scripting.KeyboardInterruptException(""));
}

The KeyboardInterruptException argument allows the Python thread to trap the ThreadAbortException and handle it as a KeyboardInterrupt.

like image 131
Jeff Hardy Avatar answered Nov 20 '22 09:11

Jeff Hardy