Нужна помощь с RX: Преобразовать System.Диагностика.Процесс.OutputDataReceived в наблюдаемый

#c# #events #system.reactive

#c# #Мероприятия #system.reactive

Вопрос:

Я хочу запустить подпроцесс и посмотреть, как он перенаправляет вывод. Для меня в C # это не проблема, но я пытаюсь понять RX, поэтому игра начинается… У меня есть статический метод расширения для процесса, который выглядит следующим образом:

     public static IObservable<IEvent<DataReceivedEventArgs>> GetOutput(this Process that)
    {
        return Observable.FromEvent<DataReceivedEventArgs>(that, "OutputDataReceived");
    }
  

Я создаю observable и подписываюсь на него следующим образом:

     Process p = ........
    var outObs = p.GetOutput();
    var outSub = outObs.Subscribe(data => Console.WriteLine(data));
  

Это не совсем неправильно, но я получаю:

 System.Collections.Generic.Event`1[System.Diagnostics.DataReceivedEventArgs]
  

пока я ожидаю получить строки:-(

Итак, я думаю, мой метод расширения возвращает неправильный тип. Было бы действительно хорошо, если бы кто-нибудь мог объяснить мне, что случилось с моей сигнатурой методов расширения.

Большое спасибо, mabra

Ответ №1:

Итак, я думаю, мой метод extensionmethod возвращает неправильный тип

Это именно то, что нужно.

IEvent переносит как sender , так и EventArgs параметры традиционного делегата события. Итак, вам нужно изменить свой код, чтобы он выглядел примерно так

 public static IObservable<string> GetOutput(this Process that)
{
    return Observable.FromEvent<DataReceivedEventArgs>(that, "OutputDataReceived")
                     .Select(ep => ep.EventArgs.Data);
}
  

Если вы используете последнюю версию Rx, тогда код немного отличается

 public static IObservable<string> GetOutput(this Process that)
{
       return Observable.FromEventPattern<DataReceivedEventArgs>(that, "OutputDataReceived")
                        .Select(ep => ep.EventArgs.Data);
}
  

ключевым моментом здесь является Select EventArgs из EventPattern / IEvent, а затем захватить Data

Комментарии:

1. Здравствуйте! Фантастически, это работает! И большое спасибо за объяснение, теперь это понятно. Rx для меня сложен 😉

2. Продолжайте с этим, это приходит вам в голову

3. Последние полученные данные всегда null — возможно ли проглотить это значение и вместо этого пометить observable как закрытый?