Как установить Observable для наблюдения за Свойством? - PullRequest
2 голосов
/ 21 июня 2019

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

Предположим, у меня есть класс

public class Foo
{
    public int FooState {get;set;}
}

и FooState обновляется очень часто. Это выглядит как идеальный случай для IObservable, тем более что мне придется отслеживать это состояние в другом классе.

public class Bar
{
    public Foo Foo {get;set;}

    private void DoStuffWithFooState()
    {
        //operate on Foo.FooState here
    }
}

Теперь я не могу изменить FooState на IObservable , потому что это сломает другие вещи, которые зависят от Foo.

Что я хотел бы сделать, так это объявить свойство IObserver в Bar, которое следит за FooState.

Разве это не основной вариант использования? Как мне это сделать?

1 Ответ

2 голосов
/ 21 июня 2019

Вы можете использовать BehaviorSubject , чтобы позволить вам превратить свойство как в наблюдаемый поток, так и в свойство, из которого вы можете просто прочитать последнее значение.

public class Foo
{
    private readonly BehaviorSubject<int> _fooSubject = new BehaviorSubject<int>(0);
    public int FooState
    {
        get => _fooSubject.Value;
        set => _fooSubject.OnNext(value);
    }
    public IObservable<int> ObservableFooState => _fooSubject;
}

Если значение FooState часто меняется, то, возможно, вы захотите использовать оператор Sample до подписки. Э.Г.

//print out value every two seconds
foo.ObservableFooState
   .Sample(TimeSpan.FromSeconds(2)) 
   .Subscribe(Console.WriteLine);

Обратите внимание, что распространенной ошибкой является использование Throttle и затем удивление, почему вы вряд ли когда-либо получите какие-либо события! (Причина в том, что Throttle сбрасывает время ожидания каждый раз, когда приходит новое событие, поэтому, когда поток часто обновляется, вы никогда не превысите значение времени ожидания.)

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

Если этот класс на самом деле является ViewModel, вы можете рассмотреть ReactiveUI , но я бы посоветовал отойти от этого, пока вы не освоитесь с Reactive.

Обратите внимание, что я не показывал логику Dispose / Completion выше. Вы должны учитывать, когда (если когда-либо) вы хотите вызвать OnCompleted для _fooSubject. Также имейте в виду, что подписки являются одноразовыми , и вы, вероятно, захотите обеспечить их удаление, когда ваши подписчики выйдут за рамки.

...