2010-02-25 3 views
1

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

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

Thanx.

ответ

1

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

Мое исправление/взлом - вызывать WaitUtilEOF на выходе AsyncStreamReader до того, как объект процесса исчезнет (необходимо использовать отражение, так как WaitUtilEOF находится во внутреннем классе платформы .NET). Это приводит к блокировке вызывающего абонента до тех пор, пока все данные асинхронизации не будут очищены через 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"); 

Успехов!