C# 并行运行多个非阻塞外部程序

ack*_*k__ 1 c# wpf multithreading external process

我需要从我的应用程序运行多个外部可执行文件的实例。此可执行文件的平均运行时间约为 3 分钟。我想重定向这些进程的输出,并更新我的 GUI 中的进度条。当然,我不想等到他们回来才能继续使用我的应用程序。

我想我应该为每个实例创建一个线程,并在线程完成时更新我的​​进度条。

这是正确的方法吗?

另外,您是否推荐了一个很好的资源/文档来了解它是如何工作的?我只找到了http://www.dotnetperls.com/threadpool

编辑:这些进程是基于网络的,即:运行时间可能会因链接延迟/带宽而有很大差异。

关于进度条,我想在每次进程完成时更新它。有处理程序吗?稍后我将根据流程输出添加更详细的更新,以增加每个执行步骤完成的进度。

编辑2:

感谢您的投入。由于我可能需要运行很多进程(最多 20 个),而且我不想使带宽饱和,我将最多并行运行 5 个进程。每次进程完成时,我都会增加进度计数器(对于我的进度条),然后运行另一个进程,直到它们全部完成,使用:

Process p = new Process();
p.StartInfo.FileName = pathToApp;
p.EnableRaisingEvents = true;
p.Exited += OnCalibrationProcessExited;
p.Start();

private void OnCalibrationProcessExited(object sender, EventArgs e)
{
  runAnotherOne function
}
Run Code Online (Sandbox Code Playgroud)

这是正确的还是有更优雅的方法来实现这一目标?当然,我不希望我的应用程序在执行过程中被阻止。为此使用后台工作人员会更好吗?

joc*_*oce 5

你应该使用ProcessProcessStartInfo。您需要设置ProcessStartInfo.UseShellExecutefalseErrorDialogfalseRedirectStandardOutputtrue(也可能是RedirectStandardError)。

您还需要为 Process 对象提供一个委托,以处理外部进程通过OutputDataReceived(也可能ErrorDataReceived是)生成的输出。

Exited您还可以设置一个委托,该委托将在进程退出时调用。

例子:

ProcessStartInfo processInfo = new ProcessStartInfo("Write500Lines.exe");
processInfo.ErrorDialog = false;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;

Process proc = Process.Start(processInfo);
proc.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null) Trace.WriteLine(errorLine.Data); };
proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) Trace.WriteLine(outputLine.Data); };
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

proc.WaitForExit();
Run Code Online (Sandbox Code Playgroud)