You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8调用Python 3.12脚本高内存场景下进程挂起问题

诊断与解决方案

你的问题核心是进程输出缓冲区阻塞导致的死锁,同时通过CMD标准输入传递激活命令的方式也可能引发环境变量传递或输出缓冲问题,以下是针对性的解决办法:

一、修复输出读取顺序,避免死锁

当前代码先读取StandardOutput再处理StandardError,当Python脚本的错误输出填满缓冲区时,进程会被阻塞无法继续执行,最终出现内存停滞、CPU归零的挂起状态。必须同时读取标准输出和错误输出:

var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "cmd",
        Arguments = "",
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        CreateNoWindow = true,
        WorkingDirectory = workingDirectory
    }
};
process.StartInfo.EnvironmentVariables.Add("TRANSFORMERS_CACHE", _transformersCacheDirectory);
process.Start();

using var sw = process.StandardInput;
if (sw.BaseStream.CanWrite)
{
    // 将激活命令和脚本命令合并为一行,减少交互步骤
    sw.WriteLine(".\\venv\\scripts\\activate && python test.py");
    sw.Flush();
    sw.Close();
}

// 并行读取输出和错误,防止缓冲区阻塞
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();

await process.WaitForExitAsync();

result = await outputTask;
var error = await errorTask;

二、直接调用虚拟环境的Python解释器(推荐方案)

绕过CMD激活步骤,直接指定虚拟环境内的Python可执行文件,既避免激活脚本的输出干扰,也能确保环境变量正确加载:

var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        // 直接指向虚拟环境的Python.exe
        FileName = Path.Combine(workingDirectory, "venv", "Scripts", "python.exe"),
        Arguments = "test.py",
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        CreateNoWindow = true,
        WorkingDirectory = workingDirectory
    }
};
process.StartInfo.EnvironmentVariables.Add("TRANSFORMERS_CACHE", _transformersCacheDirectory);
// 禁用Python输出缓冲,进一步避免阻塞
process.StartInfo.EnvironmentVariables.Add("PYTHONUNBUFFERED", "1");
process.Start();

// 无需输入激活命令,直接关闭标准输入
process.StandardInput.Close();

var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();

await process.WaitForExitAsync();

result = await outputTask;
var error = await errorTask;

三、额外排查点

  • 检查Python脚本是否有依赖终端交互的逻辑,比如等待用户输入,这种情况在无窗口进程中会导致挂起;
  • 确认系统是否对.NET进程设置了内存配额,可通过任务管理器观察.NET进程和Python进程的内存限制。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 04:56:32