Давайте назовем пример кода, размещенный здесь, перенаправителем, а другую программу - перенаправленной. Если бы это был я, я бы написал тестовую перенаправленную программу, которую можно использовать для дублирования проблемы.
Так я и сделал. Для тестовых данных я использовал спецификацию языка ECMA-334 C # v PDF; это около 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 и читать данные во время записи данных, но нет необходимости использовать асинхронное чтение. Решение может быть довольно простым. Следующее работает для меня с 5 МБ PDF.
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();
Другая возможность - использовать программу с графическим интерфейсом для перенаправления. Предыдущий код работает в приложении WPF, за исключением явных изменений.