C#路径进程冻结

C# pathping process freeze

我正在创建一个网络诊断应用程序并尝试向其中添加一个 pathping 命令,当我按下一个按钮时,它从文本字段中获取一个地址作为 ping 的路径,但是当我按下按钮时应用程序冻结并且输出中没有任何显示 window.

private void btn_PingPath_Click(object sender, EventArgs e)
{
    ProcessStartInfo PathPingStartInfo = new ProcessStartInfo();

    PathPingStartInfo.FileName = "CMD.EXE";
    PathPingStartInfo.UseShellExecute = false;
    PathPingStartInfo.CreateNoWindow = true;
    PathPingStartInfo.RedirectStandardOutput = true;
    PathPingStartInfo.RedirectStandardInput = true;
    PathPingStartInfo.RedirectStandardError = true;
    PathPingStartInfo.StandardOutputEncoding = Encoding.GetEncoding(850);

    Process PathPing = new Process();

    PathPing.StartInfo = PathPingStartInfo;
    PathPing.Start();
    PathPing.StandardInput.WriteLine("PATHPING " + txt_PingPath.Text);

    while (PathPing.StandardOutput.Peek() > -1)
    {
        txt_Output.Text = PathPing.StandardOutput.ReadLine();
    }
    while (PathPing.StandardError.Peek() > -1)
    {
        txt_Output.Text = PathPing.StandardError.ReadLine();
    }
    //txt_Output.Text = PathPing.StandardOutput.ReadToEnd();
    PathPing.WaitForExit();
}

编辑

我从另一个问题中找到了 while loop,但没有帮助。我仍然没有在输出文本 window 中得到任何输出,应用程序仍然冻结。

PATHPING 命令在退出前可能会 运行 几分钟,所以你的最后一行 PathPing.WaitForExit(); 也不会 return 几分钟(或直到路径退出)。你不能在UI线程上这样等待,因为UI也需要使用这个线程重新绘制和监听windows消息。

您可以释放 UI 线程,这样您的应用程序就不会通过创建新线程、使用 .Net 4.5+ 中的 async/await 功能或使用事件模式而冻结。以下示例使用事件模式。

private void btn_PingPath_Click(object sender, EventArgs e)
{
    ProcessStartInfo PathPingStartInfo = new ProcessStartInfo();

    PathPingStartInfo.FileName = "CMD.EXE";
    PathPingStartInfo.UseShellExecute = false;
    PathPingStartInfo.CreateNoWindow = true;
    PathPingStartInfo.RedirectStandardOutput = true;
    PathPingStartInfo.RedirectStandardInput = true;
    PathPingStartInfo.RedirectStandardError = true;
    PathPingStartInfo.StandardOutputEncoding = Encoding.GetEncoding(850);

    Process PathPing = new Process();

    PathPing.StartInfo = PathPingStartInfo;
    PathPing.Start();
    PathPing.StandardInput.WriteLine("PATHPING " + txt_PingPath.Text);
    PathPing.StandardInput.Flush();

    PathPing.OutputDataReceived += (o, args) => txt_Output.Text += args.Data;
    PathPing.ErrorDataReceived += (o, args) => txt_Output.Text += args.Data;

    PathPing.BeginErrorReadLine();
    PathPing.BeginOutputReadLine();
}