Pythonnet如何正确停止脚本执行

2024-10-02 14:26:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Pythonnet将Python脚本启动器嵌入到C#WPF应用程序中。我可以使用Scope将变量传递给python脚本,并在使用MVVM模式的控制台上获得结果。在

现在我想让用户随时停止脚本的执行。我找不到如何让它正常关闭线程。在

class PythonRuntime
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private MainViewModel viewModel;
    private string pythonCode;

    private bool runtimeThreadLock = false;
    Thread thread;

    private PyScope scope;
    private dynamic pyThread;
    private dynamic pyLock;

    ConsoleWriter consoleWriter;


    public PythonRuntime(MainViewModel viewModel, ConsoleWriter consoleWriter)
    {
        this.viewModel = viewModel;
        this.consoleWriter = consoleWriter;
        SetUpPython();    
    }

    public string PythonCode { get => pythonCode; set => pythonCode = value; }

    private void SetUpPython()
    {
        PythonEngine.Initialize(true);

        scope = Py.CreateScope();
        // consoleWriter to make python prints into C# UI
        scope.Set("Console", consoleWriter);
    }

    public void LaunchScript()
    {
        if (!runtimeThreadLock)
        {
            thread = new Thread(PythonNetTest);                
            thread.Start();
        }
    }

    public void StopScript()
    {
        // ???
    }

    [HandleProcessCorruptedStateExceptions]
    private void PythonNetTest()
    {
        runtimeThreadLock = true;
        pyThread = PythonEngine.BeginAllowThreads();
        pyLock = PythonEngine.AcquireLock();

        using (Py.GIL())
        {
            try
            {
                scope.Exec(pythonCode);
            }
            catch (PythonException exception)
            {
                consoleWriter.WriteError(exception.ToString());
            }
        }

        PythonEngine.ReleaseLock(pyLock);
        PythonEngine.EndAllowThreads(pyThread);
        runtimeThreadLock = false;
    }
}  

除了我的问题,我还想知道在using(Py.GIL())中包装代码的目的是什么。因为不管有没有,我的剧本都是一样的。在

  • Python:2.4.0
  • Python:2.7.2 32位
  • NetFramework:4.7.1

Tags: py脚本privatepublicthreadscopepythoncodevoid
1条回答
网友
1楼 · 发布于 2024-10-02 14:26:58

好吧,我刚开始做嵌入CPython的工作,可能只知道比你多一点。什么警告。。。在

首先,需要终止脚本。执行此操作时,对.Exec()的调用将返回,线程将退出。如果脚本运行的时间有限,那么您只需等待它。否则,你必须安排一些信号让它退出。在

其次,主线将等待线程完成,使用在:How to wait for thread to finish with .NET?中描述的几种.NET模式之一

using(Py.GIL())PythonEngine.AcquireLock();的简写,PythonEngine.ReleaseLock(pyLock);它创建一个IDisposable对象,该对象获取锁,然后在Dispose()上释放它。所以,在你的例子中,这是多余的。在

我不确定你打电话给BeginAllowThreads()的效果。文档说它释放锁以允许其他线程。当你叫它的时候,你没有GIL。下一行获得GIL。因此,它对我来说似乎没有任何作用。在

有关线程的详细信息,请参见https://docs.python.org/3/c-api/init.html。这似乎与python线程化和保存线程状态有关,以便可以完成其他非python的事情。这是python3。Python2似乎不支持类似的功能。在

相关问题 更多 >