.NET Core 6 Web API调用Python代码报错:多次调用失败及BinaryFormatter问题
问题修复方案
核心问题分析
- Python引擎重复初始化/关闭:每次API调用都执行
PythonEngine.Initialize()和PythonEngine.Shutdown()是错误的,PythonNet的引擎不支持多次初始化与关闭操作。 - BinaryFormatter禁用限制:.NET Core 6默认禁用了
BinaryFormatter,而PythonNet的Shutdown()方法内部依赖该序列化方式,导致抛出异常。
具体修复步骤
1. 全局初始化/关闭Python引擎
将Python引擎的初始化移至应用启动阶段,关闭移至应用停止阶段,而非每次API调用执行:
- 在
Program.cs中添加初始化代码(应用启动时执行一次):var builder = WebApplication.CreateBuilder(args); // 配置PythonNet Runtime.PythonDLL = "python311.dll"; // 若DLL不在系统PATH,需写绝对路径 PythonEngine.Initialize(); // 其他服务配置... builder.Services.AddControllers(); var app = builder.Build(); // 注册应用停止时的回调,关闭Python引擎 app.Lifetime.ApplicationStopping.Register(() => { PythonEngine.Shutdown(); }); // 中间件配置... app.MapControllers(); app.Run();
2. 启用BinaryFormatter支持
在项目中开启允许BinaryFormatter序列化的配置,有两种方式:
- 方式一:修改项目文件(.csproj)
在<PropertyGroup>节点内添加:<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization> - 方式二:修改runtimeconfig.json
在项目生成的.runtimeconfig.json文件中添加:{ "runtimeOptions": { "configProperties": { "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true } } }
3. 调整API方法代码
移除API方法内的PythonEngine.Initialize()和PythonEngine.Shutdown()调用,仅保留GIL的获取与释放:
string fileLoc = AppDomain.CurrentDomain.BaseDirectory; try { using (Py.GIL()) { dynamic module = Py.Import("PythonSampleIronPython"); dynamic result = module.calculator.xl2determination(fileLoc); // 根据实际需求将Python返回值转换为C#对象,示例: // return result.As<Audit>(); return new Audit(); } } catch (Exception err) { _logger.LogError("Unable to evaluate model", err); throw new Exception("Unable to evaluate model", err); }
4. 额外注意事项
- 确保
python311.dll的路径正确,若Python未安装在系统默认路径,需指定绝对路径(如@"C:\Python311\python311.dll")。 - 若Python脚本不在默认搜索路径,需设置Python的搜索路径:
// 在初始化PythonEngine后添加 string scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "你的脚本目录"); PythonEngine.PythonPath = $"{PythonEngine.PythonPath};{scriptPath}"; - 多次调用时,
using (Py.GIL())块必须每次请求都执行,确保正确获取和释放全局解释器锁。
内容的提问来源于stack exchange,提问作者as2007
相关产品推荐
相关产品推荐

