Улучшения API процессов в .NET 11. Продолжение
Обзор
Проблемы существующего API
Чтобы решить проблему, описанную в предыдущем посте, были добавлены несколько новых функций.
Process.ReadAllText и Process.ReadAllTextAsync
Одновременно обрабатывают стандартный вывод и ошибки, что помогает избежать взаимоблокировок. Они декодируют вывод, используя кодировку, указанную в ProcessStartInfo.Standard[Output/Error]Encoding (или кодировку по умолчанию, если она не указана), и возвращают результат в виде строки. Теперь код с чтением вывода и ошибок процесса стал намного проще:
ProcessStartInfo startInfo = new("dotnet", "--help")
{
RedirectStandardOutput = true,
RedirectStandardError = true
};
using Process p = new() { StartInfo = startInfo };
p.Start();
(string output, string error) = p.ReadAllText();
p.WaitForExit();Process.RunAndCaptureText и Process.RunAndCaptureTextAsync
Поскольку код выше – очень распространенная практика, эти методы производят запуск процесса, чтение всех выходных данных и ошибок и ожидание завершения процесса в одном вызове:
ProcessTextOutput output =
Process.RunAndCaptureText("dotnet", ["--help"]);
Process.Run и Process.RunAsync
Не захватывают вывод и ошибки, а просто ждут завершения:
ProcessExitStatus status = Process.Run("dotnet", ["build", "-c", "Release"]);Process.ReadAllLines и Process.ReadAllLinesAsync
Пригодятся, если нужно получать вывод и ошибки в виде набора строк. Возвращают перечислимый объект ProcessOutputLine:
using Process p = Process.Start(…);
await foreach (var line in p.ReadAllLinesAsync())
{
if (line.StandardError)
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(line.Content);
Console.ResetColor();
}
Process.ReadAllBytes и Process.ReadAllBytesAsync
Позволяют получить вывод и ошибки в виде массивов байт.
Тайм-ауты и отмена
Все вышеупомянутые методы поддерживают тайм-ауты и отмену. Если тайм-аут достигнут или токен отмены отменён до достижения конца потока, методы выбросят исключение TimeoutException или OperationCanceledException соответственно. Методы верхнего уровня RunAndCaptureText[Async] и Run[Async] также попытаются завершить процесс.
Мультиплексирование и другие оптимизации «под капотом»
Новые методы не только проще в использовании, но и быстрее. В фоновом режиме синхронные методы Process.RunAndCaptureText и Process.ReadAll[Bytes/Text] используют мультиплексирование (poll в Unix и WaitForMultipleObjects в Windows) для чтения как из stdout, так и из stderr с использованием одного потока. Они также реализуют ряд других оптимизаций, таких как использование ArrayPool для уменьшения выделения памяти. Асинхронные методы Process.RunAndCaptureTextAsync и Process.ReadAllTextAsync используют асинхронные операции ввода-вывода без блокировки каких-либо потоков.
Окончание следует…
Источник: https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/