Skip to content

Interrupting running Python code from another thread #766

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

Closed
jduncalf opened this issue Nov 6, 2018 · 11 comments · Fixed by #1337
Closed

Interrupting running Python code from another thread #766

jduncalf opened this issue Nov 6, 2018 · 11 comments · Fixed by #1337
Milestone

Comments

@jduncalf
Copy link

jduncalf commented Nov 6, 2018

Hi, does anyone know the best way to stop a currently running PyScope.Exec() call. My C# app is multi-threaded and allows users to run scripts, however where there's an infinite loop, new Python calls can be executed but I can't stop the original infinite loop.

Thanks.

@filmor
Copy link
Member

filmor commented Nov 6, 2018

See here https://stackoverflow.com/questions/1420957/stopping-embedded-python.

We currently do not expose Py_AddPendingCall, though, but assuming we did (there is PR #692 that uses it), you could probably translate the given example like this:

class Interrupter
{
    public Interrupter()
    {
        _interruptAction = DoInterrupt;
    }

    int DoInterrupt(IntPtr arg)
    {
        Exceptions.SetError(Exceptions.KeyboardInterrupt, "interrupted");
    }

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    delegate int PendingCall(IntPtr arg);
    readonly PendingCall _interruptAction;

    void Interrupt()
    {
        IntPtr func = Marshal.GetFunctionPointerForDelegate(_interruptAction);
        Runtime.Py_AddPendingCall(func, IntPtr.Zero);
    }
}

All Runtime functions are internal, so you will have to work within pythonnet's codebase itself. A PR adding an Interrupt() function on PythonEngine and PyScope would be highly appreciated :)

@jduncalf
Copy link
Author

jduncalf commented Nov 6, 2018

Many thanks, i'll do that.

@jduncalf
Copy link
Author

jduncalf commented Nov 7, 2018

Hi, unfortunately I can't get this to work. I basically used the Interrupter class you posted above, but the DoInterrupt() callback never gets invoked.

Any ideas?

@jduncalf
Copy link
Author

jduncalf commented Nov 7, 2018

Hi filmor, apologies, got it working. Had to change my C# host apps threading model. As a COM/DCOM MTA server the .exe primary thread was not the thread which eventually called PyEval_InitThreads, which is required for the Py_AddPendingCall supplied callback to work.

Thanks again.

@filmor filmor changed the title Intentional infinite loop Interrupting running Python code from another thread Nov 7, 2018
@filmor
Copy link
Member

filmor commented Nov 7, 2018

Nice, I'll see whether I can prepare a PR that includes this.

@filmor filmor added this to the 3.0.0 milestone Nov 15, 2018
@amos402
Copy link
Member

amos402 commented Nov 23, 2018

@jduncalf I think this extension should be help https://github.com/amos402/py-xtimeout

@den-run-ai
Copy link
Contributor

anyone would like to submit a PR?

@amos402
Copy link
Member

amos402 commented Jan 17, 2019

I think this is not a problem that relate to pythonnet, the extension I supplied above can handle this case.
Or you can reference here to make a trace callback when you try to interrupt the work thread.
https://github.com/amos402/py-xtimeout/blob/3f17f5ed050045cd8dc13987ce2abb0187501f88/xtimeout/_xtimeout.cpp#L358-L379
https://github.com/amos402/py-xtimeout/blob/3f17f5ed050045cd8dc13987ce2abb0187501f88/xtimeout/_xtimeout.cpp#L86-L95

@heartacker
Copy link

heartacker commented Aug 14, 2020

@heartacker i have the same requirement of stopping runing code embbed in wpf. if there is any easy way to stop them. tell me thanks

@kerol2r20
Copy link

I also meet this situation. Is there any idea to stop running script which embedded in C#?
thanks

@TheCollegedude
Copy link

I also meet this situation. Is there any idea to stop running script which embedded in C#?
thanks

it seems we have to wait for 3.0.0

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

Successfully merging a pull request may close this issue.

7 participants