You need to enable JavaScript to run this app. 如何在C# WinForm中异步调用远程服务器的多个PowerShell脚本
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# WinForm中异步调用远程服务器的多个PowerShell脚本

异步改造实现方案

你可以将原同步方法改造为符合.NET TAP异步任务模型的实现,适配WinForm场景不会阻塞UI线程,改造后的代码如下:

public async Task<string> NewPsSessionAsync(string ServerName, string command)
{
    // 使用using自动管理资源生命周期,避免手动释放遗漏
    using Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    using PowerShell psSession = PowerShell.Create();

    psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine  
    + "Invoke-Command -session $sessions -ScriptBlock {" + command + "}" + Environment.NewLine                 
    + "Remove-PSSession -Session $sessions" + Environment.NewLine);

    psSession.Commands.AddCommand("Out-String");

    Collection<PSObject> results = new Collection<PSObject>();
    try
    {
        // 把PowerShell原生APM异步模式转为TAP模式,支持async/await调用
        results = await Task.Factory.FromAsync(psSession.BeginInvoke(), psSession.EndInvoke);
    }
    catch (Exception ex)
    {
        results.Add(new PSObject((object)ex.Message));
    }
    runspace.Close(); 

    StringBuilder stringBuilder = new StringBuilder();
    foreach (PSObject obj in results)
    {
        stringBuilder.AppendLine(obj.ToString());
    }

    return stringBuilder.ToString(); 
}

WinForm端调用说明

  • 调用时必须搭配async/await语法,不要使用Wait()或.Result,避免UI线程死锁
  • await执行完成后会自动切回WinForm UI线程,可直接对窗体控件赋值,无需额外处理跨线程访问问题

调用示例:

// 按钮点击事件处理方法
private async void btnRunScript_Click(object sender, EventArgs e)
{
    btnRunScript.Enabled = false;
    txtOutput.Text = "脚本执行中,请稍候...";
    try
    {
        string execResult = await NewPsSessionAsync(txtServer.Text, txtScript.Text);
        txtOutput.Text = execResult;
    }
    catch (Exception ex)
    {
        txtOutput.Text = $"执行出错:{ex.Message}";
    }
    finally
    {
        btnRunScript.Enabled = true;
    }
}

核心改动点

  • 方法返回值从string修改为Task<string>,方法名新增Async后缀符合.NET异步命名规范
  • 替换同步Invoke()调用为异步实现,不会阻塞调用线程
  • 新增using关键字自动释放Runspace和PowerShell对象,避免资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 07:06:01