Open psxbox opened 3 days ago
I changed the C# code and the problem was solved
private async Task Test((string fileName, (string name, string desription, string type, string version)) item)
{
try
{
using (GIL.Acquire())
{
var fileName = Path.GetFileNameWithoutExtension(item.fileName);
using PyObject module = Import.ImportModule(fileName);
using var infoFunc = module.GetAttr("test");
var testStr = "Hello, World!";
using var pyStr = PyObject.From(testStr);
using var result = infoFunc.Call(pyStr);
var info = result.As<string>();
if (info != testStr)
{
throw new Exception("Test failed");
}
}
}
catch (Exception ex)
{
await jsRuntime.InvokeVoidAsync("alert", ex.Message);
logger.LogError(ex, "Test failed");
return;
}
await jsRuntime.InvokeVoidAsync("alert", "Test passed");
}
I think your problem was the await
call while holding on to the GIL. The PyGILState_Release
documentation says that the GIL must be released on the same thread it was acquired on:
Every call to
PyGILState_Ensure()
must be matched by a call toPyGILState_Release()
on the same thread.
However, the await
call can potentially complete or wake up on a different thread than when it started awaiting. This is why moving the await
outside the using
fixes the problem. That said, two things:
await
boundary.On point 2, I think the exception here is Import.ImportModule
, which doesn't acquire & release the GIL internally:
and neither does CPythonAPI.Import
that is delegates to:
@tonybaloney can probably comment on whether Import.ImportModule
was designed for public consumption or that this is an oversight.
Thank you! I understand what it is. But unfortunately, I wanted to use it in a multitasking app.
I wanted to use it in a multitasking app.
Right, but do you need the GIL for that? Couldn't you use a standard lock or synchronisation primitive to coordinate the work between the threads in your application?
Error in calling python method from Blazor app:
Python file:
C# code: