Создать наблюдаемый на метод - PullRequest
0 голосов
/ 27 мая 2018

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

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

Проблема, с которой я сталкиваюсь, заключается в следующем: как создать наблюдаемую информацию для вызываемого метода?Ниже приведен мой пример кода.

//This method is invoked every time an update happens on the server
public virtual void MessageHandler(MyObject1 object1, MyObject2 object2)
{
    Observable.Create<MyObject3>(observer =>
        {
            var object3 = new MyObject3(object1, object2);
            observer.OnNext(object3 );

            return Disposable.Empty;
        })
        .Subscribe(x => WriteLine($"Message acknowledged"));
}

Но это создает наблюдаемое для каждого вызова метода, а не то, что мне нужно, и тоже не похоже на правильный подход.Я также читал, что использование «Subject» или «AsyncSubject» не является правильным способом решения проблем.

1 Ответ

0 голосов
/ 27 мая 2018

Правило о неиспользовании Subject - это правило, которое не очень хорошо выражено.

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

Если вы используете Subject в качестве источника для наблюдаемых и , вы правильно инкапсулируете Subject и ты запутываешь это, тогда ты в порядке.Поэтому обычно это означает использование поля private, к которому может получить доступ только ваш код (поэтому никто не может вызвать .OnCompleted() для него и вызвать .AsObservable(), чтобы никто не смог преобразовать вашу наблюдаемую информацию обратно в базовый Subject.

В вашем случае вы напрямую подписываетесь, поэтому .AsObservable() не требуется, но я подозреваю, что это просто демонстрационный код. В реальном мире убедитесь, что вы запутываете.

Вот что выкод должен выглядеть следующим образом:

private Subject<MyObject3> _subject = new Subject<MyObject3>();

private void SetUpObservable()
{
    _subject = new Subject<MyObject3>();
    _subject.Subscribe(x => Console.WriteLine($"Message acknowledged"));
}

public virtual void MessageHandler(MyObject1 object1, MyObject2 object2)
{
    _subject.OnNext(new MyObject3(object1, object2));
}

Теперь, если вы все еще хотите избежать Subject, вы можете сделать это в качестве альтернативы:

private Action<MyObject3> _delegate;

private void SetUpObservable()
{
    Observable
        .FromEvent<MyObject3>(h => _delegate += h, h => _delegate -= h)
        .Subscribe(x => Console.WriteLine($"Message acknowledged"));
}

public virtual void MessageHandler(MyObject1 object1, MyObject2 object2)
{
    _delegate?.Invoke(new MyObject3(object1, object2));
}

На мой взгляд, Subject дает вам лучший контроль, и его легче настроить.

В любом случае вам, вероятно, следует сохранить подписку IDisposable, чтобы вы могли правильно очистить.

...