Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В .NET шаблон конструктора наблюдателя реализуется как набор интерфейсов. Интерфейс System.IObservable<T> представляет поставщика данных, который также отвечает за предоставление IDisposable реализации, позволяющей наблюдателям отписываться от уведомлений. Интерфейс System.IObserver<T> представляет наблюдателя. В этом разделе описаны рекомендации, которые разработчики должны следовать при реализации шаблона проектирования наблюдателя с помощью этих интерфейсов.
Нарезание резьбы
Как правило, поставщик реализует IObservable<T>.Subscribe метод путем добавления определенного наблюдателя в список подписчиков, представленный некоторым объектом коллекции, и он реализует IDisposable.Dispose метод, удаляя конкретного наблюдателя из списка подписчиков. Наблюдатель может вызывать эти методы в любое время. Кроме того, поскольку контракт поставщика или наблюдателя не указывает, кто несет ответственность за отмену подписки после метода обратного IObserver<T>.OnCompleted вызова, поставщик и наблюдатель могут попытаться удалить одного и того же члена из списка. Из-за этой возможности методы Subscribe и Dispose должны быть потокобезопасными. Как правило, это предполагает использование параллельной коллекции или блокировки. Реализации, которые не являются потокобезопасными, должны явно указывать это в документации.
Все дополнительные гарантии должны быть указаны в слое поверх контракта поставщика или наблюдателя. Исполнители должны четко указывать, когда они накладывают дополнительные требования, чтобы избежать путаницы пользователей в отношении контракта условий наблюдения.
Обработка исключений
В связи со слабой связью между поставщиком данных и наблюдателем, исключения в шаблоне проектирования наблюдателя носят информационный характер. Это влияет на то, как поставщики и наблюдатели обрабатывают исключения в шаблоне проектирования наблюдателя.
Поставщик— вызов метода OnError
Этот OnError метод предназначен как информационное сообщение наблюдателям, так же как и метод IObserver<T>.OnNext. OnNext Однако метод предназначен для предоставления наблюдателя текущих или обновленных данных, а OnError метод предназначен для указания того, что поставщик не может предоставить допустимые данные.
Поставщик должен следовать этим рекомендациям при обработке исключений и вызове OnError метода:
Поставщик должен обрабатывать собственные исключения, если он имеет определенные требования.
Поставщик не должен ожидать или требовать, чтобы наблюдатели обрабатывали исключения определенным образом.
Поставщик должен вызвать OnError метод, когда он обрабатывает исключение, которое компрометирует возможность предоставления обновлений. Сведения о таких исключениях можно передать наблюдателю. В других случаях нет необходимости уведомлять наблюдателей об исключении.
После того как поставщик вызовет метод OnError или IObserver<T>.OnCompleted, не должно быть дальнейших уведомлений, и поставщик может отменить подписку своих наблюдателей. Однако наблюдатели также могут отменить подписку в любое время, включая как до, так и после получения OnError или IObserver<T>.OnCompleted уведомления. Шаблон проектирования наблюдателя не определяет, отвечает ли поставщик или наблюдатель за отмену подписки; Таким образом, существует вероятность того, что оба могут попытаться отменить подписку. Как правило, при отмене подписки наблюдатели удаляются из коллекции подписчиков. В однопоточном приложении данная реализация должна убедиться в том, что ссылка на объект действительна и что объект является членом коллекции подписчиков, прежде чем пытаться удалить его. В многопоточных приложениях следует использовать объект коллекции, безопасный для потоков, например объект System.Collections.Concurrent.BlockingCollection<T>.
Наблюдатель — реализация метода OnError
Когда наблюдатель получает уведомление об ошибке от поставщика, наблюдатель должен рассматривать исключение как информационное и не должен принимать каких-либо конкретных действий.
Наблюдатель должен следовать этим рекомендациям при реагировании на OnError вызов метода от поставщика:
Наблюдатель не должен выбрасывать исключения из своих реализаций интерфейса, таких как OnNext или OnError. Тем не менее, если наблюдатель создает исключения, он должен ожидать, что эти исключения будут необработанными.
Чтобы сохранить стек вызовов, наблюдатель, который хочет вызвать объект, переданный Exception методу OnError , должен упаковать исключение перед его вызовом. Для этой цели следует использовать стандартный объект исключения.
Дополнительные рекомендации
Попытка отменить регистрацию в методе IObservable<T>.Subscribe может привести к пустой ссылке. Поэтому рекомендуется избежать этой практики.
Хотя наблюдатель можно подключить к нескольким поставщикам, рекомендуется подключить IObserver<T> экземпляр только к одному IObservable<T> экземпляру.