Как наблюдать зависимые события в Reactive Extensions (Rx)? - PullRequest
2 голосов
/ 08 апреля 2011

Каков наилучший способ обработки зависимых событий, таких как;
Есть объект, для которого мне нужно проверить, успешно ли установлено соединение или нет. Но объект сначала должен пройти этап инициализации, который я тестирую на успех или неудачу, а затем перейти к этапу подключения.

  • Если инициализация завершается неудачно, возвращается, если соединение не установлено.
  • Если инициализация прошла успешно, возвращение является результатом шага соединения.

Мой код указан ниже. Есть ли лучший способ обработки этих зависимых событий, потому что я подписываюсь на соединение внутри подписки инициализации?

Если у меня будет больше зависимых событий, как это, я буду продолжать вкладывать подписки?

public static void Test()
{
    const int maxValue = 501;

    var random = new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0));

    var initOk = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => true);
    var initKo = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => false);

    var connectOk = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => true);
    var connectKo = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => false);

    var initResult = initOk.Amb(initKo).Take(1);
    var connectResult = connectOk.Amb(connectKo).Take(1);

    var id =
        initResult.Subscribe(ir =>
                                 {
                                     if (ir)
                                     {
                                         var cd =
                                             connectResult.Subscribe(cr =>
                                                                         {
                                                                             Console.WriteLine(cr
                                                                                                   ? "Connection succeeded."
                                                                                                   : "Connection failed.");
                                                                         });
                                     }
                                     else
                                     {
                                         Console.WriteLine("Initialization failed thus connection failed.");
                                     }
                                 });
}

Ответы [ 2 ]

2 голосов
/ 08 апреля 2011

Обычно вы можете избежать вложения, используя различные операторы rx для цепочки вызовов.

Ваш пример может быть приведен в порядок с помощью:

initResult.SelectMany(ir =>
       {   
           if (ir != null)
           {
             return connectResult;
           }

           Console.WriteLine("Initialization failed thus connection failed.");

           return Observable.Throw(new Exception("Some Exception"));
       })
       .Subscribe(cr =>
           {
              Console.WriteLine(cr != null
                 ? "Connection succeeded." 
                 : "Connection failed.");
           })
0 голосов
/ 09 апреля 2011

Вы можете использовать это:

var finalResult =
    initResult
        .Select(ir =>
            Observable.If(() => ir, connectResult, Observable.Return(false)))
        .Merge();

Чтобы получать свои сообщения, вы можете изменить его следующим образом:

var initResultText =
    initResult
        .Select(ir =>
            ir ? (string)null : "Initialization failed thus connection failed.");

var connectResultText =
    connectResult
        .Select(cr => 
            String.Format("Connection {0}.", cr ? "succeeded" : "failed"));

var finalResult =
    initResultText
        .Select(irt =>
            Observable.If(() =>
                irt == null, connectResultText, Observable.Return(irt)))
        .Merge();

Если вам нужно вложить больше, чем это, вы должны рассмотретьсоздание метода расширения, который оборачивает сложность и, следовательно, композицию, будет намного проще.

...