Назвемо зразок коду, розміщеного тут, переспрямований, а інша програма перенаправлена. Якби це я, я, мабуть, написав би тестову перенаправлену програму, яку можна використати для дублювання проблеми.
Так я і зробив. Для тестових даних я використовував специфікацію мови ECMA-334 C #vv; це приблизно 5 Мб. Далі важлива частина цього.
StreamReader stream = null;
try { stream = new StreamReader(Path); }
catch (Exception ex)
{
Console.Error.WriteLine("Input open error: " + ex.Message);
return;
}
Console.SetIn(stream);
int datasize = 0;
try
{
string record = Console.ReadLine();
while (record != null)
{
datasize += record.Length + 2;
record = Console.ReadLine();
Console.WriteLine(record);
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
return;
}
Значення розміру даних не відповідає фактичному розміру файлу, але це не має значення. Незрозуміло, чи PDF-файл завжди використовує як CR, так і LF в кінці рядків, але це не має значення для цього. Для тестування можна використовувати будь-який інший великий текстовий файл.
За допомогою цього коду переспрямовуючого зразка висить, коли я записую велику кількість даних, але не тоді, коли пишу невелику кількість.
Я дуже намагався якось простежити виконання цього коду, і не зміг. Я прокоментував рядки перенаправленої програми, які відключили створення консолі для перенаправленої програми, щоб спробувати отримати окреме вікно консолі, але не зміг.
Потім я знайшов Як запустити консольний додаток у новому вікні, батьківському вікні чи без вікна . Отже, мабуть, ми не можемо (легко) мати окрему консоль, коли одна програма консолі запускає іншу консольну програму без ShellExecute, і оскільки ShellExecute не підтримує перенаправлення, ми повинні мати спільну консоль, навіть якщо ми не вказали вікна для іншого процесу.
Я припускаю, що якщо перенаправлена програма десь заповнює буфер, вона повинна чекати, коли дані будуть прочитані, і якщо в цей момент передіректор не зчитує ніяких даних, то це буде тупиком.
Рішення полягає в тому, щоб не використовувати ReadToEnd і читати дані під час запису даних, але не потрібно використовувати асинхронні зчитування. Рішення може бути досить простим. Наступне працює для мене з PDF-файлом розміром 5 Мб.
ProcessStartInfo info = new ProcessStartInfo(TheProgram);
info.CreateNoWindow = true;
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);
string record = p.StandardOutput.ReadLine();
while (record != null)
{
Console.WriteLine(record);
record = p.StandardOutput.ReadLine();
}
p.WaitForExit();
Інша можливість полягає у використанні програми GUI для перенаправлення. Попередній код працює у програмі WPF, за винятком явних модифікацій.