2

我正在通过 pythonnet https://github.com/pythonnet/pythonnet在我的 C# 应用程序中嵌入 Python

我正在产生工作线程(一次一个),产生的 python 子解释器在隔离环境中做一些工作并结束子解释器。一切正常,直到我使用 pymongo,然后 Py_EndInterpreter 开始失败。

Py_EndInterpreter(PyThreadState *tstate)
{
    PyInterpreterState *interp = tstate->interp;

    if (tstate != PyThreadState_GET())
        Py_FatalError("Py_EndInterpreter: thread is not current");
    if (tstate->frame != NULL)
        Py_FatalError("Py_EndInterpreter: thread still has a frame");
    if (tstate != interp->tstate_head || tstate->next != NULL)
        Py_FatalError("Py_EndInterpreter: not the last thread");

    PyImport_Cleanup();
    PyInterpreterState_Clear(interp);
    PyThreadState_Swap(NULL);
    PyInterpreterState_Delete(interp);
}

它失败了

if (tstate != interp->tstate_head || tstate->next != NULL)
    Py_FatalError("Py_EndInterpreter: not the last thread");

现在我真的不知道如何处理它并使代码正常工作。我正在做的非常简短的版本,失败是

            Runtime.Py_Initialize();
            Runtime.PyEval_InitThreads();

            IntPtr thread_state = Runtime.PyEval_SaveThread();


            IntPtr gil = Runtime.PyGILState_Ensure();

            int i = 0;
            while (i < 5)
            {
                AutoResetEvent resetEvent = new AutoResetEvent(false);               
                BackgroundWorker worker = new BackgroundWorker();
                worker.DoWork += (o, ea) =>
                {
                    Thread.Sleep(2000);
                    IntPtr interpreter = Runtime.Py_NewInterpreter();

                    string str = @"
import pymongo
client = pymongo.MongoClient(""localhost"")";
                    Runtime.PyRun_SimpleString(str);
                    Runtime.Py_EndInterpreter(interpreter);

                    resetEvent.Set();
                };
                worker.RunWorkerAsync();
                resetEvent.WaitOne();

                i++;
            }

            Runtime.PyThreadState_Swap(thread_state);
            Runtime.PyGILState_Release(gil);

            Runtime.PyEval_RestoreThread(thread_state);
            Runtime.Py_Finalize();
4

1 回答 1

2

看起来 pymongo 创建了自己的线程(用于连接池),在这种情况下,更难以控制解释器的状态并优雅地关闭它。另一方面,尝试在脚本本身中执行此操作:

                    string str = @"
import pymongo
client = pymongo.MongoClient(""localhost"")
client.close()";

医生说:

关()

断开与 MongoDB 的连接。

关闭连接池中的所有套接字并停止监控 线程

于 2015-12-24T23:28:21.590 回答