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

WebAPI多请求时远程异步执行PowerShell脚本异常及RunspacePool问题

问题分析与解决方案

一、多请求仅处理第一个的原因

  • Runspace过早关闭:你的代码在pipeline.InvokeAsync()后仅等待到Pipeline进入Running状态就立即关闭Runspace,但远程文件复制脚本耗时较长,此时脚本实际仍在执行。Runspace关闭会直接终止远程会话,加上WinRM默认的并发会话限制,后续请求无法创建新会话,导致仅第一个请求能正常处理。
  • 未等待异步执行完成:InvokeAsync()是非阻塞调用,当前等待逻辑仅确认脚本启动,而非等待执行完毕。多请求场景下,前一个请求提前释放的会话资源可能处于异常占用状态,导致后续请求无法建立连接。
  • WinRM并发会话限制:默认情况下,Windows远程管理(WinRM)对单用户的并发PowerShell会话数有限制(默认5个),如果每个请求都创建Runspace但未正确释放,会快速耗尽配额,阻断后续请求。

二、RunspaceFactory.CreateRunspacePool重载不支持的原因

你尝试使用的RunspaceFactory.CreateRunspacePool(int minRunspaces, int maxRunspaces, RunspaceConnectionInfo connectionInfo)重载,仅存在于PowerShell 7+(基于.NET Core/.NET 5+)对应的System.Management.Automation程序集中。若你的项目引用的是Windows PowerShell 5.1的程序集(通常位于C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation),该重载不存在,会提示方法不支持。

修复建议

针对多请求问题

  1. 等待脚本执行完成再关闭Runspace:替换现有等待逻辑,确保脚本执行完毕后再释放资源:
    pipeline.InvokeAsync();
    // 等待脚本执行结束(Running状态为执行中)
    while (pipeline.PipelineStateInfo.State == PipelineState.Running)
    {
        await Task.Delay(100);
    }
    // 检查执行状态
    if (pipeline.PipelineStateInfo.State == PipelineState.Failed)
    {
        Logger.Error("脚本执行失败: " + pipeline.PipelineStateInfo.Reason?.Message);
    }
    
  2. 调整WinRM会话限制(临时方案):若使用Windows PowerShell 5.1,可通过命令提升并发会话数:
    winrm set winrm/config/winrs @{MaxShellsPerUser="10"}
    

针对RunspacePool重载问题

  1. 升级到PowerShell 7+:将项目依赖替换为PowerShell 7对应的NuGet包Microsoft.PowerShell.SDK,即可使用目标重载创建Runspace池,实现会话复用:
    // 全局初始化Runspace池(建议单例)
    var runspacePool = RunspaceFactory.CreateRunspacePool(1, 5, connectionInfo);
    runspacePool.Open();
    
    // 处理请求时从池获取会话
    using (var ps = PowerShell.Create())
    {
        ps.RunspacePool = runspacePool;
        var command = new Command(ConfigurationManager.AppSettings["ScriptPath"].ToString());
        command.Parameters.Add("inputobj", ConvertModeltoPsobject(obj));
        ps.Commands.AddCommand(command);
        await ps.InvokeAsync();
        // 处理执行结果
    }
    
  2. Windows PowerShell下的替代方案:使用无connectionInfo的重载,手动配置会话连接信息:
    var runspacePool = RunspaceFactory.CreateRunspacePool(1, 5);
    runspacePool.RunspaceCreationProperties = new RunspaceCreationProperties();
    runspacePool.RunspaceCreationProperties.ConnectionInfo = connectionInfo;
    runspacePool.Open();
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:01:35