Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script Shutdown() doesn't stop running python script #1312

Open
DJSures opened this issue Jan 24, 2022 · 3 comments
Open

Script Shutdown() doesn't stop running python script #1312

DJSures opened this issue Jan 24, 2022 · 3 comments

Comments

@DJSures
Copy link

DJSures commented Jan 24, 2022

Description

The Python script is running a loop in a thread. The runtime.Shutdown() should stop the running python script. It does not.

Steps to Reproduce

This example will demonstrate how the python script contains a loop in a thread. A button to stop the running script by calling Shutdown() is not doing anything.

     public class StreamWriteEvent : MemoryStream {

      public event EventHandler<string> OnNewText;

      public override void Write(byte[] buffer, int offset, int count) {

        OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));

        base.Write(buffer, offset, count);
      }

      public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {

        OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));

        return base.WriteAsync(buffer, offset, count, cancellationToken);
      }

      public override void WriteByte(byte value) {

        OnNewText?.Invoke(this, value.ToString());

        base.WriteByte(value);
      }

      public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {

        OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));

        return base.BeginWrite(buffer, offset, count, callback, state);
      }
    }

    ScriptEngine _engine;
    ScriptScope _scope;

    // Run a python script in a new thread
    private void button2_Click(object sender, EventArgs e) {

      Thread ts = new Thread(runScript);
      ts.Start();
    }

    // This thread is running the python script
    void runScript() {

      var streamWriter = new StreamWriteEvent();
      streamWriter.OnNewText += StreamWriter_OnNewText;

      _engine = IronPython.Hosting.Python.CreateEngine();

      _engine.Runtime.IO.SetErrorOutput(streamWriter, Encoding.ASCII);
      _engine.Runtime.IO.SetOutput(streamWriter, Encoding.ASCII);

      _scope = _engine.CreateScope();

      // Run a script that loops
      // We will test both capturing the output stream & the Shutdown command to stop the running script
      var sc = _engine.CreateScriptSourceFromString(@"
while True:
  print('This should output something')
");

      var ret = sc.Execute(_scope);

      // This doesn't do anything. It doesn't stop the running script.
      Console.WriteLine("Shut down");
    }

    private void StreamWriter_OnNewText(object sender, string e) {

      // This should output but never does
      Console.WriteLine("From steam writer" + e);
    }

    // This is the button that should stop the running python script
    private void button3_Click(object sender, EventArgs e) {

      Console.WriteLine("Shutting down...");

      // This shutdown command doesn't work. The script will continue running.
      _scope.Engine.Runtime.Shutdown();
    }

Expected behavior:
The running python script should stop

Actual behavior:
The running python script does not stop

Versions

3.4.0-alpha1 for .Net Framework 4.7.2 from nuget

@slozier
Copy link
Contributor

slozier commented Jan 24, 2022

Shutdown doesn't actually stop a running script as far as I can tell all it does is some cleanup.

Here's a comment I found about it on the old mailing list (https://mail.python.org/pipermail/ironpython-users/2014-March/016895.html):

The only way to forcibly end it is to run it in another thread and use
Thread.Abort. All of the usual caveats around Thread.Abort apply, and
your atexit may or may not be called.

The Shutdown method is a bit misleading; it does some cleanup but doesn't
actually stop the current engine. There really isn't any way to do that,
and any implementation would probably be the moral equivalent of
Thread.Abort anyway.

@DJSures
Copy link
Author

DJSures commented Jan 26, 2022

Okay - Thread.Abort gives me shivers but I'll work with that. Thanks again

@DJSures
Copy link
Author

DJSures commented Feb 19, 2024

Thread.Abort() is obsolete and does not work with .net8 at all. What other option do we have to stop a running script from another thread in c#?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants