使用 Diagnostics.Process 时,会阻止 WinForms C# 5.0 中的 UI

问题描述 投票:0回答:1

我需要创建运行不同命令(PowerShell.exe、ipconfig 等)的应用程序,但是当调用 ExecuteCommand 时,UI 会冻结,直到工作完成。

尝试使用 await proc.StandardOutput.ReadToEndAsync() 运行该方法,但不起作用。 (它挂在提到的行上,不会在下一行继续)

我做错了什么?

提前致谢。

执行命令:

    public static async Task<string> ExecuteCommand(string command)
    {
        try
        {
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.RedirectStandardInput = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;

            proc.StartInfo = procStartInfo;
            proc.Start();

            proc.WaitForExit();
            var message = proc.StandardOutput.ReadToEndAsync();

            //var error =  await proc.StandardError.ReadToEndAsync();

            proc.Close();

            //var errorContent = error;
            return message.Result;
        }
        catch (Exception objException)
        {
            return objException.Message;
        }
    }

记录器:

public void Logger(string value)
{
    logtxt.AppendText("[" + DateTime.Now + "]: " + value + Environment.NewLine);
    logtxt.SelectionStart = logtxt.Text.Length;
    logtxt.ScrollToCaret();
}

处于活动状态:

private async Task<bool> IsActive()
{
    string text = await ExecuteCommand("PowerShell.exe -Command \"Get-VPNconnection -AllUserConnection\"");

    Logger(text);

    ...more code...
}

Form1_Shown(我从 Form_Load 中移出了以下代码,因为 UI 出现需要一些时间):

private void Form1_Shown(object sender, EventArgs e)
{
    if (IsActive().Result)
    {
      ...more code...
    }
}
c# powershell winforms cmd task
1个回答
0
投票

这是你的问题:

private void Form1_Shown(object sender, EventArgs e)
{
    if (IsActive().Result)
    {
      ...more code...
    }
}

读取

Result
属性是一个阻塞操作。它不仅会阻塞 UI 线程,更糟糕的是,它会导致死锁,因为异步流程中有
await
正在捕获 UI 上下文,因为它们没有配置
.ConfiguredAwait(false)
。解决这个问题的正确方法是走async-all-the-way:

private async void Form1_Shown(object sender, EventArgs e)
{
    if (await IsActive())
    {
      ...more code...
    }
}

您可以通过阅读 Stephen Cleary 的著名文章不要阻止异步代码来了解有关此常见问题的更多信息。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.