В Rx существует три основных метода: OnNext<T>
, OnError
и OnComplete
, и только OnNext
должен передавать данные.Использование исключения в качестве объекта передачи данных в реактивных расширениях
У меня есть данные с точками времени и данными, когда есть нормальные значения, которые передаются через OnNext и учитывают более 99% точек данных. Но тогда некоторые точки данных являются исключительными, например. отложенные данные или неточные данные, которые переписывают историю. Логично следующее: Событие по данным, требующим специального лечения, но не следующие данные в ожидаемом порядке.
«Нормально» в этом случае передавать исключительные значения через канал OnError
? Я мог бы определить OutOfOrderDataExcpetion<T> : Exception
с свойством типа T
и обработать его в наблюдателе. Учитывая, что исключительные значения являются редкими, и я не делаю исключения/создания исключений, но создаю их и использую их как DTO, производительность не должна быть проблемой.
Меня беспокоит то, что метод называется OnError
, а не OnException
, но мои данные не являются ошибкой, ему просто нужна специальная обработка. В то же время, если я выставляю свой наблюдаемый внешний код, который ничего не знает о OutOfOrderExcpetion<T>
, внешний код не сможет его поймать, и это будет ошибкой.
Я мог бы следить за шаблоном поиска событий и обернуть каждое событие данных в оболочку с помощью команды и полезной нагрузки, но тогда мне нужно будет распаковать каждую команду, а в 99% + случаях она будет той же командой «next». Использование OnError
в качестве канала для всех остальных команд дает мне почти тот же шаблон источника событий с упрощенной обработкой.
Помимо проблемы с именами, не могли бы вы добавить некоторые аргументы, которые помешают мне использовать этот дизайн? Или это правильное использование исключений?
Это очень хороший момент, что OnError может быть «одним и единственным», спасибо! У вас есть ссылка на документы? И если «нормальные» потребители следуют спецификациям, они прекратятся и отпишутся и не будут видеть следующую ошибку, что именно проблема с «специальными подписчиками», которая выдержит особые исключения? –
В [MSDN] (https://msdn.microsoft.com/en-us/library/dd783449 (v = vs.110) .aspx) формулировка «обычно называется» для каждого метода, я не могу быстро найти ссылку на строгий договор, который вы упоминаете. «последовательность завершена» обозначается «OnComplete», почему тогда существует этот специальный метод завершения, если можно использовать 'OperationCancelledException', как в TPL, когда задача отменяется маркером отмены? –
@ V.B. - Взгляните на http://go.microsoft.com/fwlink/?LinkID=205219 - в частности, часть о Rx Grammar - «Сообщения, отправленные в экземпляры интерфейса IObserver, следуют следующей грамматике:« OnNext * (OnCompleted | OnError)? '. Эта грамматика позволяет наблюдаемым последовательностям отправлять любое количество (0 и более) сообщений OnNext в подписанный экземпляр наблюдателя, необязательно сопровождаемый единственным сообщением об успешном (OnCompleted) или сбое (OnError)." – Enigmativity