2016-07-13 3 views
4

Мне не удалось найти окончательного ответа на вопрос о том, как можно отказаться от подписки на Observable, на который подписаны Observable.subscribe(...). Здесь есть еще один ответ SO (Event and Observable in FSharp), который идет мучительно близко, но явно не указывает, как это достигается, если только я чего-то не упускаю.F #: отписаться от FSharp.Control.Reactive.Observable

Звонок Observable.subscribe(someSubscriptionFunction) возвращает IDisposable. Нужно ли мне просто .Dispose() его удалить someSubscriptionFunction (и только он), или это повлияет на Observable, а также на любые другие подписки на это Observable?

+0

Зачем вам нужно. Но если вы это сделаете, тогда он будет распоряжаться подпиской. Вы также можете использовать gjallarhorn. – s952163

ответ

3

Прежде всего вам нужно отказаться от подписки, если вы хотите прекратить получать уведомления до того, как наблюдатель обычно прекратит их отправку (например, перед запуском OnCompleted или OnError).

Для того чтобы получить представление о том, как ведут себя наблюдаемые, возможно, наиболее очевидно, чтобы посмотреть за интерфейсом F # на базовую библиотеку.

Намерение IDisposable возвращенного Observable.subscribe является то, что он отписывается один IObserver от IObservable.

Поставщик должен реализовать единый метод Subscribe, который указывает , что наблюдатель хочет получать push-уведомления. Вызывающие к метод передает экземпляр наблюдателя. Метод возвращает реализацию IDisposable, которая позволяет наблюдателям отменить уведомления в любое время до того, как поставщик прекратит отправку .

(Source)

Вы можете увидеть это поведение от example реализации представленной здесь (в C#, к сожалению, страница отсутствует F # образцов):

Соответствующий фрагмент кода является:

private class Unsubscriber : IDisposable 
{ 
    private List<IObserver<Location>>_observers; 
    private IObserver<Location> _observer; 

    public Unsubscriber(List<IObserver<Location>> observers, IObserver<Location> observer) 
    { 
     this._observers = observers; 
     this._observer = observer; 
    } 

    public void Dispose() 
    { 
     if (_observer != null && _observers.Contains(_observer)) 
      _observers.Remove(_observer); 
    } 
} 

Конечно, потому что это интерфейсы, вы полностью во власти исполнителя с точки зрения реального поведения.


Таким образом, с точки зрения фактического удаления подписки, да, все, что вам нужно сделать, это Dispose()IDisposable и нет, это не должно оказывать влияние на других наблюдателей.

Вы также можете использовать ключевые слова use или using, а не явно вызывать dispose. См. this page для получения дополнительной информации.

Смежные вопросы