2016-02-21 44 views
0

我创建一个网络诊断应用程序,并尝试将PathPing命令添加到它那里需要一个ADRESS从一个文本框的路径来ping当我按下一个按钮,但应用程序冻结当我按下按钮,输出窗口中不显示任何内容。C#的pathping过程冻结

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

+0

预计这种'PathPing.WaitForExit();'不要在你的代码的最后一行..看起来像你的逻辑是关闭 – MethodMan

+0

@MethodMan你能解释为什么它看起来像我的逻辑是关闭? – user5825579

回答

1

PATHPING命令最终可能会在退出之前运行几分钟,所以最后一行PathPing.WaitForExit();也不会在几分钟内返回(或直到退出)。您不能在UI线程上这样等待,因为UI还需要使用此线程重新绘制并侦听Windows消息。

您可以释放UI线程在.net 4.5+使通过创建一个新的线程或使用异步应用程序犯规冻结/等待功能,或使用事件模式。以下示例使用事件模式。

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(); 
} 
+0

这将引发''System.InvalidOperationException''在'System.Windows.Forms.dll'告诉我,跨线程操作无效:'控制‘txt_Output’从比它创建on.'的线程以外的线程访问? – user5825579

+0

这个错误是因为你想从不同的线程比它创建一个访问UI对象(在这种情况下,txt_Outpu)。您需要调用'txt_Output.Invoke(...)'将上下文切换回UI线程。您在这里看到您的问题和评论似乎很明显,您并不真正了解线程是如何工作的 - 我建议您自己做一些研究,它会为您节省很多头痛,并且之前已经询问过所有这些问题。 SOF。 – caesay