Python.Net页面https://github.com/pythonnet/pythonnet说:
“所有对python的调用都应该在here (Py.GIL()) {/* --这里的代码-- */}块中。”
我有一个调用.Net dll的Python应用程序。.Net dll启动一个新线程,该线程完成一些工作,然后调用Python。如果我将回调包装为"using (Py.GIL())“,那么当Python线程完成时,我的代码会打印以下错误:
Fatal Python error: auto-releasing thread-state, but no thread-state for this thread
Python runtime state: finalizing (tstate=00890970)我的代码故意让函数python_callback在主Python线程完成时仍在处理回调。当主要Python线程完成时,我希望所有东西都干净地停止。
如果我没有将回调包装在“the (Py.GIL())”中,那么它可以正常工作。所以我的问题是:
从.Net到.Net的回调是否需要包装在“the (Py.GIL())”中?
如果是:如何避免此错误消息?
Python代码:
import time
from datetime import datetime
import clr
clr.AddReference("System")
clr.AddReference(r"C:\MyDotNet\MyDotNet.dll")
import System
from MyDotNet import MyDotNetClass
def main():
print(datetime.now(), 'Python started')
dot_net_obj = MyDotNetClass(System.Action[System.Object](python_callback))
time.sleep(10)
print(datetime.now(), 'Python main thread finished')
def python_callback(arg):
print(datetime.now(), 'Python: In callback, arg =', arg)
time.sleep(20) # <-- to keep the callback running when the main thread finishes
if __name__ == '__main__':
main().Net代码:
using System;
using System.Threading;
using Python.Runtime;
namespace MyDotNet
{
public class MyDotNetClass
{
public MyDotNetClass(Delegate callback)
{
new Thread(() =>
{
Thread.Sleep(3000);
using (Py.GIL()) // <--- Is it safe to remove this 'using (Py.GIL())'?
{
object[] paramToPass = new object[1];
paramToPass[0] = "The C# work is done";
callback.DynamicInvoke(paramToPass);
}
}).Start();
}
}
}这是输出:
2020-11-23 10:10:30.168585 Python started
2020-11-23 10:10:33.191054 Python: In callback, arg = The C# work is done
2020-11-23 10:10:40.191273 Python main thread finished
Fatal Python error: auto-releasing thread-state, but no thread-state for this thread
Python runtime state: finalizing (tstate=00890970)使用Python3.8,Python.Net 2.5.1,.Net框架4.6.1
发布于 2020-11-25 05:18:20
是的,如果涉及线程的话。参见Python.NET回购中的一个问题
https://stackoverflow.com/questions/64967321
复制相似问题