Если все процессы завершаются после выполнения, используйте это вместо внутреннего while:
p1.WaitForExit();
sw.Write(sr.ReadToEnd());
Если вы хотите, чтобы время процессов истекло:
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:
Кажется, вы пытаетесь связать вывод каждого процесса со следующим. Если это так, вы пропускаете p1 = p2
в конце цикла.
Также рассмотрите возможность вывести первый процесс запуска из цикла: это сделает ваш код намного более читабельным. Установка p1
StartInfo должна быть перемещена в блок if (i == 0)
, если вы оставите его таким образом. По моему мнению, перемещение вывода для чтения из последнего процесса также не будет плохой идеей ...
Edit:
Это мое решение (с тайм-аутом):
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:
Алгоритм, ожидающий завершения каждого процесса:
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();
Я переместил первый процесс из цикла, чтобы избавиться от условного. Таким образом, поток управления проще и проще добавить привязанность кода к первому процессу.