Dear PythonNet group,
I am working on a c# project which would like to access functions written
in python from time to time. Below is a wrapper function.
I have a unittest setup for this function. Everytime I run this unittest,
it will get information from python world as I desired.
public ScriptContext GetContextFromScript()
{
ScriptContext scriptContext;
try
{
if (!PythonEngine.IsInitialized)
PythonEngine.Initialize();
var threadState = PythonEngine.BeginAllowThreads();
var gilState = PythonEngine.AcquireLock();
PyObject mod =
PythonEngine.ImportModule(this.GetModuleName());
PyObject instance = mod.InvokeMethod("Strategy", new
PyTuple());
scriptContext
=(ScriptContext)instance.InvokeMethod("SetContext", new
PyTuple()).AsManagedObject(typeof (ScriptContext));
PythonEngine.ReleaseLock(gilState);
PythonEngine.EndAllowThreads(threadState);
PythonEngine.Shutdown();
}
catch (Exception ex)
{
throw;
}
return scriptContext;
}
However, when I launch the UI and call this function by clicking some
button, the program hangs at PythonEngine.Initialize().
After debugging into the PythonNet source code, I found when calling
through UI, the RunTime.Initialize() will return true for
Runtime.Py_IsInitialized().
internal static void Initialize()
{
is32bit = IntPtr.Size == 4;
if (0 == Runtime.Py_IsInitialized())
{
Runtime.Py_Initialize();
}
if (0 == Runtime.PyEval_ThreadsInitialized())
{
Runtime.PyEval_InitThreads();
}
}
And the whole initialize process will hang when result.Dispose() is called.
It actually trying to acquire lock but cannot get it.
using (StreamReader reader = new StreamReader(stream))
{
// add the contents of clr.py to the module
string clr_py = reader.ReadToEnd();
PyObject result = RunString(clr_py, module_globals,
locals.Handle);
if (null == result)
throw new PythonException();
result.Dispose();
}
It looks like something happend before code reaching this pythong wrapper
function. PythonEninge is partially initialized with
Runtime.Py_IsInitialized() = true and Runtime.PyEval_ThreadsInitialized() =
false.
Questions
1. what could be the possible cause for this situation?
2. If I cannot find the root cause and put BegineAllowThreads() there, what
could be a solution for it?
Many thanks!
Jian