1

我在我的 C# 项目中逐行读取另一个 exe 的控制台,该项目成功读取了每个控制台行,但我面临的问题是当 exe 开始执行时,我的 c# 表单挂起,它一直等到外部 exe 没有完全执行.

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = EXELOCATION;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = argv;
startInfo.RedirectStandardOutput = true;
try
{
    // Start the process with the info we specified.
    // Call WaitForExit and then the using statement will close.
    using (exeProcess = Process.Start(startInfo))
    {
        using (StreamReader reader = exeProcess.StandardOutput)
        {
            string result;
            while ((result = reader.ReadLine() ) != null)
            {                            
                scanning.Text = result;
                scanning.Refresh();
                Console.Write(result);
            }
        }

    }

我该如何解决这个问题,请指导我

4

4 回答 4

2

您可以使用Process.OutputDataReceivedMSDN

它允许附加一个事件处理程序,只要数据可用,该处理程序就会被调用。

using (exeProcess = Process.Start(startInfo))
{
    exeProcess.OutputDataReceived +=
        (sender, args) =>
            {
                scanning.Text = args.Data;
                scanning.Refresh();
                Console.Write(args.Data);
            };

    exeProcess.BeginOutputReadLine();

    // do whatever you want here

    exeProcess.WaitForExit();
}

无论如何,如果你在 UI 线程中这样做,它仍然会阻塞 UI。

另外,如果你想从另一个线程更新 UI 控件的内容,你应该调用BeginInvoke().

在那种情况下,BackgroundWorker是一个很好的帮助。它将为您创建后台线程;ProgressChanged您可以在事件处理程序中安全地更新 UI 。

于 2013-10-08T11:04:43.517 回答
1

您应该使用BackgroundWorker

使用后台工作者:

以下是使用 BackgroundWorker 的最少步骤:

  • 实例化 BackgroundWorker 并处理 DoWork 事件。
  • 调用 RunWorkerAsync,可选择使用对象参数。

然后,这使它开始运转。传递给 RunWorkerAsync 的任何参数都将通过事件参数的 Argument 属性转发给 DoWork 的事件处理程序。这是一个例子:

class Program
{
  static BackgroundWorker _bw = new BackgroundWorker();

  static void Main()
  {
    _bw.DoWork += bw_DoWork;
    _bw.RunWorkerAsync ("Message to worker");
    Console.ReadLine();
  }

  static void bw_DoWork (object sender, DoWorkEventArgs e)
  {
    // This is called on the worker thread
    Console.WriteLine (e.Argument);        // writes "Message to worker"
    // Perform time-consuming task...
  }
}
于 2013-10-08T11:07:55.757 回答
0

如果您在单个阻塞线程中执行所有操作,那么您的应用程序将不得不等到另一个 exe 将控制权返回给您的表单。

解决方案是在单独的线程中进行读取,该线程将在信息可用时将信息传递回您的应用程序。这稍微复杂一些,但做起来并不难——您应该阅读可用的线程类,例如 Background Worker。

于 2013-10-08T11:04:05.950 回答
0

我建议学习线程。最好和最简单的入门方法是 Winforms 中的Background Worker类。

但是您也应该检查System.Threading命名空间。

于 2013-10-08T11:02:40.987 回答