Я пытаюсь захватить вывод из tail в режиме отслеживания, где он выводит текст при обнаружении изменений в длине файла - особенно полезно для следующих файлов журнала при добавлении строк. По какой-то причине мой вызов StandardOutput.Read () блокируется до полного выхода tail.exe.
Пример соответствующего кода:
var p = new Process() {
StartInfo = new ProcessStartInfo("tail.exe") {
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = "-f c:\\test.log"
}
};
p.Start();
// the following thread blocks until the process exits
Task.Factory.StartNew(() => p.StandardOutput.Read());
// main thread wait until child process exits
p.WaitForExit();
Я также пытался использовать поддержку обработчика событий OutputDataReceived
, который демонстрирует такое же поведение блокировки:
p.OutputDataReceived += (proc, data) => {
if (data != null && data.Data != null) {
Console.WriteLine(data.Data);
}
};
p.BeginOutputReadLine();
У меня есть немного больше кода вокруг вызова StandardOutput.Read (), но это упрощает пример и все еще демонстрирует нежелательное поведение блокировки. Что еще я могу сделать, чтобы мой код реагировал на доступность данных в потоке StandardOutput до выхода дочернего приложения?
Возможно, это просто причуды работы tail.exe? Я использую версию 2.0, скомпилированную как часть пакета UnxUtils.
Обновление: это, по-видимому, хотя бы частично связано с причудами в tail.exe. Я взял двоичный файл из проекта GnuWin32 как часть пакета CoreUtils, и версия поднялась до 5.3.0. Если я использую опцию -f
, чтобы следовать без повторов, я получаю страшную проблему «плохого дескриптора файла» в STDERR (легко игнорируемую), и процесс немедленно завершается. Если я использую опцию -F
для включения повторных попыток, она, кажется, работает правильно после того, как пришло сообщение о плохом дескрипторе файла, и она пытается открыть файл во второй раз.
Возможно, я мог бы попробовать более свежую сборку win32 из репозитория coreutils git?