Appelons l'exemple de code publié ici le redirecteur et l'autre programme le redirigé. Si c'était moi, j'écrirais probablement un programme de test redirigé qui peut être utilisé pour dupliquer le problème.
Alors je l'ai fait. Pour les données de test, j'ai utilisé le PDF de spécification du langage ECMA-334 C #; c'est environ 5 Mo. Ce qui suit est la partie importante de cela.
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;
}
La valeur de la taille de données ne correspond pas à la taille réelle du fichier, mais cela n'a pas d'importance. Il n'est pas clair si un fichier PDF utilise toujours CR et LF à la fin des lignes, mais cela n'a pas d'importance pour cela. Vous pouvez utiliser n'importe quel autre fichier texte volumineux pour tester.
En utilisant cela, l'exemple de code de redirecteur se bloque lorsque j'écris la grande quantité de données, mais pas lorsque j'écris une petite quantité.
J'ai beaucoup essayé de retracer l'exécution de ce code et je n'ai pas pu. J'ai commenté les lignes du programme redirigé qui ont désactivé la création d'une console pour le programme redirigé pour essayer d'obtenir une fenêtre de console séparée, mais je ne pouvais pas.
Ensuite, j'ai trouvé Comment démarrer une application console dans une nouvelle fenêtre, la fenêtre du parent ou aucune fenêtre . Donc, apparemment, nous ne pouvons pas (facilement) avoir une console séparée lorsqu'un programme de console démarre un autre programme de console sans ShellExecute et puisque ShellExecute ne prend pas en charge la redirection, nous devons partager une console, même si nous ne spécifions aucune fenêtre pour l'autre processus.
Je suppose que si le programme redirigé remplit une mémoire tampon quelque part, il doit attendre que les données soient lues et si, à ce stade, aucune donnée n'est lue par le redirecteur, il s'agit d'un blocage.
La solution est de ne pas utiliser ReadToEnd et de lire les données pendant l'écriture des données, mais il n'est pas nécessaire d'utiliser des lectures asynchrones. La solution peut être assez simple. Ce qui suit fonctionne pour moi avec le PDF de 5 Mo.
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();
Une autre possibilité est d'utiliser un programme GUI pour effectuer la redirection. Le code précédent fonctionne dans une application WPF, sauf avec des modifications évidentes.