If all processes exit after execution, use this instead of the internal one, but:
p1.WaitForExit(); sw.Write(sr.ReadToEnd());
If you want processes not to run:
int i = 0; while (!p1.HasExited && i < maxWaits) { Thread.Sleep(delay); i++; } sw.Write(sr.ReadToEnd()); //Kill process if running: if (!p1.HasExited) { try { p1.Kill(); } catch { } }
Edit:
It seems you are trying to bind the output of each process to the next. If in this case you are missing p1 = p2 at the end of the loop.
Also, consider moving the first run from the loop: it will make your code more readable. Setting p1 StartInfo should be moved to the if (i == 0) block if (i == 0) if you leave it this way. Moving the output read by the last process would not be a bad idea, in my opinion ...
Edit:
This is my solution (with timeout):
int maxWaits = 10; // Wait 1 second at most. int delay = 100; var p = new Process(); p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = asProcesses[0]; p.StartInfo.UseShellExecute = false; p.Start(); foreach (var path in asProcesses.Skip(1)) { var p2 = new Process(); p2.StartInfo.FileName = path; p2.StartInfo.RedirectStandardInput = true; p2.StartInfo.RedirectStandardOutput = true; p2.StartInfo.UseShellExecute = false; { int i = 0; while (!p.HasExited && i < maxWaits) { p2.StandardInput.Write(p.StandardOutput.ReadToEnd()); //Redirect IO. This line means that the second process can start calculations if the first is long-running and writes its output progressively. Thread.Sleep(delay); i++; } } p2.StandardInput.Write(p.StandardOutput.ReadToEnd()); //Redirect last output from p. { //Kill process if still running: if (!p.HasExited) { try { p.Kill(); } catch { } } } } { int i = 0; while (!p.HasExited && i < maxWaits) { Thread.Sleep(delay); i++; } } string result = p.StandardOutput.ReadToEnd(); { if (!p.HasExited) { try { p.Kill(); } catch { } } }
Edit:
An algorithm waiting for each process to exit:
var p = new Process(); p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = asProcesses[0]; p.StartInfo.UseShellExecute = false; p.Start(); foreach (var path in asProcesses.Skip(1)) { var p2 = new Process(); p2.StartInfo.FileName = path; p2.StartInfo.RedirectStandardInput = true; p2.StartInfo.RedirectStandardOutput = true; p2.StartInfo.UseShellExecute = false; p.WaitForExit(); p2.StandardInput.Write(p.StandardOutput.ReadToEnd()); } p.WaitForExit(); string result = p.StandardOutput.ReadToEnd();
I moved the first process out of the loop to get rid of the conditional. Thus, the control flow is simpler and easier to add code binding to the first process.
source share