Как я могу проверить ошибки внутри метода RX finally? - PullRequest
2 голосов
/ 01 апреля 2011

Следующий код выдает ошибку в итераторе (специально для тестирования).Как вы можете видеть, подписка легко получает исключение, используя параметр onError метода Subscribe, но я не могу понять, как метод finally может проверить / получить исключение (и, следовательно, изменитьповедение в зависимости от результата)

static void Main(string[] args)
{
    // pseudo sequence
    var sequence = Observable.GenerateWithTime(
            (double)0, 
            i => i < 10, 
            i => i += 0.5, 
            i => {
                if(i < 6) return i;

                throw new InvalidOperationException();
            },
            i => TimeSpan.FromSeconds(1)
            ).Timestamp().Finally(() => Console.WriteLine("finally!"));


    using (
        sequence.Subscribe(x =>
            {
                Console.WriteLine(x);
            },
            err => Console.WriteLine(err.ToString())  // Write error to console
        )
    )
    {
            Console.ReadLine();
    }

    Console.ReadLine();
}

Примечание. Этот код предназначен только для демонстрационных целей, но он работает:)

Обновление

приведенная выше демонстрация позволила желаемое поведение - благодаря Джеймсу Хэю.

    static void Main(string[] args)
    {
        bool errored = false;
        var sequence = Observable.GenerateWithTime(
                (double)0,
                i => i < 10,
                i => i += 0.5,
                i =>
                {
                    if (i < 6) return i;

                    throw new InvalidOperationException();
                },
                i => TimeSpan.FromSeconds(1)
                ).Catch(
                    new Func<Exception, IObservable<double>>(x => {
                        errored = true;
                        return Observable.Return((double)0);
                    })
                ).Timestamp().Finally(() => Console.WriteLine("finally!" + (errored?"(errored)":"")));

        using (
            sequence.Subscribe(objects =>
                {
                    Console.WriteLine(objects);
                },
                err => Console.WriteLine(err.ToString())
            )
        )
        {
                Console.ReadLine();
        }

        Console.ReadLine();
    }

1 Ответ

4 голосов
/ 01 апреля 2011

Finally произойдет после возникновения ошибки ИЛИ последовательность завершится. Так что может не быть ошибки, когда выполнение попадает в оператор «Окончание».

Если вы хотите, чтобы что-то происходило в последовательности при возникновении ошибки, посмотрите на оператор Catch.

Чтобы вы могли добавить побочный эффект и повторно выдать ошибку:

.Catch(ex =>
{
   //Add a side effect here

   return Observable.Throw(ex); 
})

Или вы можете просто обработать ошибку и продолжить последовательность таким образом:

.Catch(ex => Observable.Return("Some continue on error observable")));
...