C#路径进程冻结

时间:2016-02-21 00:24:08

标签: c# process visual-studio-2015 deadlock

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

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,但没有帮助。我仍然在输出文本窗口中没有输出,应用程序仍然冻结。

1 个答案:

答案 0 :(得分:1)

PATHPING命令在退出前可能会运行几分钟,因此您的最后一行PathPing.WaitForExit();也不会返回几分钟(或直到路径退出)。您不能在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();
}