Chiamiamo il codice di esempio pubblicato qui il redirector e l'altro programma il reindirizzato. Se fossi in me, probabilmente scriverei un programma di reindirizzamento di prova che può essere utilizzato per duplicare il problema.
Così ho fatto. Per i dati di test ho usato l'ECMA-334 C # Specifica del linguaggio PDF; è di circa 5 MB. Quella che segue è la parte importante di ciò.
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;
}
Il valore del datasize non corrisponde alla dimensione effettiva del file ma non ha importanza. Non è chiaro se un file PDF utilizza sempre sia CR che LF alla fine delle righe, ma non importa per questo. È possibile utilizzare qualsiasi altro file di testo di grandi dimensioni con cui eseguire il test.
Usando quello il codice redirector di esempio si blocca quando scrivo la grande quantità di dati ma non quando scrivo una piccola quantità.
Ho provato moltissimo a rintracciare in qualche modo l'esecuzione di quel codice e non ci sono riuscito. Ho commentato le righe del programma reindirizzato che ha disabilitato la creazione di una console per il programma reindirizzato per tentare di ottenere una finestra console separata ma non ci sono riuscito.
Poi ho trovato Come avviare un'app console in una nuova finestra, la finestra del genitore o nessuna finestra . Quindi apparentemente non possiamo (facilmente) avere una console separata quando un programma console avvia un altro programma console senza ShellExecute e poiché ShellExecute non supporta il reindirizzamento, dobbiamo condividere una console, anche se non specifichiamo alcuna finestra per l'altro processo.
Suppongo che se il programma reindirizzato riempie un buffer da qualche parte, allora deve attendere che i dati vengano letti e se a quel punto nessun dato viene letto dal redirector allora è un deadlock.
La soluzione è non usare ReadToEnd e leggere i dati mentre i dati vengono scritti ma non è necessario utilizzare le letture asincrone. La soluzione può essere abbastanza semplice. Quanto segue funziona per me con il PDF da 5 MB.
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();
Un'altra possibilità è utilizzare un programma GUI per eseguire il reindirizzamento. Il codice precedente funziona in un'applicazione WPF tranne che con ovvie modifiche.