在 C# 中读取另一个 exe 的控制台挂起 UI
本文关键字:控制台 挂起 UI exe 另一个 读取 | 更新日期: 2023-09-27 18:34:34
我正在逐行读取 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);
}
}
}
我应该如何解决这个问题,请指导我
您可以使用
Process.OutputDataReceived
(MSDN(
它允许附加一个事件处理程序,只要数据可用,就会调用该处理程序。
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。
你应该使用 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...
}
}
我建议学习线程。最好和最简单的入门方法是 WinForms 中的后台辅助角色类。
但是你也应该看看 System.Threading 命名空间。
如果您在单个阻塞线程中执行所有操作,那么您的应用程序将不得不等到另一个 exe 将控制权返回到您的表单。
解决方案是在单独的线程中进行读取,这会在信息可用时将信息传递回应用程序。这稍微复杂一些,但并不难做到 - 您应该阅读可用的线程类,例如后台工作线程。