我需要从我的应用程序运行外部可执行文件的多个实例。该可执行文件的平均运行时间约为 3 分钟。
我想重定向这些进程的输出,并更新 GUI 中的进度条。
当然,我不想等到他们回来才能继续使用我的应用程序。
我认为我应该为每个实例创建一个线程,并在线程完成时更新我的进度条。
这是正确的做法吗?
另外,您是否推荐一个好的资源/文档来了解它是如何工作的?我找到了http://www.dotnetperls.com/threadpool only.
编辑:这些过程是基于网络的,即:运行时间可能会根据链接延迟/带宽而有很大差异。
关于进度条,我想在每次进程完成时更新它。有处理程序吗?稍后我将根据流程输出添加更详细的更新,以增加每个执行步骤完成的进度。
edit 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
}
这是正确的还是有更优雅的方法来实现这一目标?
当然,我不希望我的应用程序在执行过程中被阻止。
为此使用后台工作者是否更好?
你应该使用Process and ProcessStartInfo。
你需要设置ProcessStartInfo.UseShellExecute
to false
, ErrorDialog
to false
, RedirectStandardOutput
to true
(并且可能RedirectStandardError
too).
您还需要向 Process 对象提供委托,以处理外部进程生成的输出OutputDataReceived
(并且可能ErrorDataReceived
以及)。
还有一个Exited
您可以设置当进程退出时将调用的委托。
Example:
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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)