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

C#异步调用PowerShell获取多厂商显卡进程GPU使用率实现问询

C# 异步调用PowerShell获取自身进程GPU使用率的正确实现

前置依赖

首先你需要安装PowerShell SDK的NuGet包:System.Management.Automation,选择和你项目目标框架匹配的版本即可。

问题原因

你原有代码里BeginInvoke()返回的是IAsyncResult类型的异步操作句柄,不是PowerShell的执行结果,直接调用ToString()只会输出类型名称,自然无法拿到GPU使用率数值。

推荐实现方案(async/await 无阻塞)

我们直接把当前进程ID传入PowerShell脚本,避免脚本写死进程名的问题,同时用异步等待的方式获取结果,完成后再更新UI:

using System;
using System.Diagnostics;
using System.Management.Automation;
using System.Threading.Tasks;

// 异步获取GPU使用率的方法
public async Task<string> GetCurrentProcessGpuUsageAsync()
{
    // 直接内嵌PowerShell脚本,替换进程ID为当前进程ID,避免读取外部文件
    string script = $@"
    $p = Get-Process -Id {Process.GetCurrentProcess().Id}; 
    ((Get-Counter ""\GPU Engine(pid_$($p.id)*engtype_3D)\Utilization Percentage"").CounterSamples | where CookedValue).CookedValue | foreach {{Write-Output ""$([math]::Round($_,1))%""}}
    ";

    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript(script);
        // 异步调用PowerShell并等待结果
        var results = await ps.InvokeAsync();
        
        // 处理执行错误
        if (ps.HadErrors)
        {
            foreach (var error in ps.Streams.Error)
            {
                Debug.WriteLine(error.ToString());
            }
            return "获取失败";
        }

        // 返回第一个有效结果
        if (results.Count > 0)
        {
            return results[0].BaseObject.ToString();
        }
        return "0%";
    }
}

UI更新调用示例

因为UI控件只能在UI线程更新,调用的时候根据你用的UI框架做对应处理即可:

WinForm 示例

private async void UpdateGpuInfoBtn_Click(object sender, EventArgs e)
{
    string gpuUsage = await GetCurrentProcessGpuUsageAsync();
    // 直接赋值即可,await会自动回到UI线程上下文
    gpuinfobox.Text = gpuUsage;
}

WPF 示例

和WinForm调用逻辑一致,await后直接赋值给控件属性即可。

可选回调式实现(不使用async/await)

如果你需要用传统回调的方式处理,也可以用BeginInvoke加回调的写法:

public void GetCurrentProcessGpuUsageAsync(Action<string> callback)
{
    string script = $@"
    $p = Get-Process -Id {Process.GetCurrentProcess().Id}; 
    ((Get-Counter ""\GPU Engine(pid_$($p.id)*engtype_3D)\Utilization Percentage"").CounterSamples | where CookedValue).CookedValue | foreach {{Write-Output ""$([math]::Round($_,1))%""}}
    ";

    PowerShell ps = PowerShell.Create();
    ps.AddScript(script);
    ps.BeginInvoke(null, null, ar =>
    {
        try
        {
            var results = ps.EndInvoke(ar);
            string res = ps.HadErrors || results.Count == 0 ? "获取失败" : results[0].BaseObject.ToString();
            // 回调返回结果,更新UI需要主动调度到UI线程
            this.Invoke((Action)(() => gpuinfobox.Text = res));
        }
        finally
        {
            ps.Dispose();
        }
    }, null);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:45:09