Проблема с потоком StandardOutput в асинхронном режиме - PullRequest
2 голосов
/ 25 февраля 2010

У меня есть программа, которая запускает процессы командной строки в асинхронном режиме, используя BeginOutputReadLine. Моя проблема заключается в том, что событие .Exited срабатывает, когда все еще происходят некоторые события .OutputDataReceived. То, что я делаю в моем событии .Exited, должно произойти только после того, как все мои события .OutputDataReceived будут выполнены, или я пропущу некоторые выходные данные.

Я заглянул в класс Process, чтобы узнать, может ли что-нибудь быть полезным для меня, например, дождаться, пока поток не станет пустым, но я нахожу только для режима синхронизации. Может ли кто-нибудь из вас помочь?

Thanx.

1 Ответ

2 голосов
/ 30 апреля 2010

Я столкнулся с подобной проблемой: мое приложение по сути является внешним интерфейсом для некоторых приложений cygwin, и иногда приложение закрывается до того, как все данные получены через событие OutputDataReceived, и я теряю данные.

Мое исправление / хак - вызывать WaitUtilEOF на выходе AsyncStreamReader до исчезновения объекта процесса (необходимо использовать отражение, поскольку WaitUtilEOF находится во внутреннем классе .NET Framework). Это приводит к блокировке вызывающей стороны до тех пор, пока все асинхронные данные не будут сброшены через OutputDataReceived. Я не уверен, что это решит вашу проблему напрямую, но это может помочь ...

private static void WaitUntilAsyncStreamReachesEndOfFile(Process process, string field)
{
    FieldInfo asyncStreamReaderField = typeof(Process).GetField(field, BindingFlags.NonPublic | BindingFlags.Instance);
    object asyncStreamReader = asyncStreamReaderField.GetValue(process);

    Type asyncStreamReaderType = asyncStreamReader.GetType();

    MethodInfo waitUtilEofMethod = asyncStreamReaderType.GetMethod(@"WaitUtilEOF", BindingFlags.NonPublic | BindingFlags.Instance);

    object[] empty = new object[] { };

    waitUtilEofMethod.Invoke(asyncStreamReader, empty);
}

И я называю это так:

WaitUntilAsyncStreamReachesEndOfFile(process, "output");

Удачи!

...