在方法上创建一个observable

时间:2018-05-26 22:41:41

标签: c# .net-core system.reactive

在我的应用程序中,我有一个方法,每次在服务器上的某个队列上发生更新时都会调用该方法。应用程序已初始化为以这种方式运行。

现在,每次使用最新数据调用该方法时,我都希望将其视为事件流的一部分,从而使其成为永远不会以订阅者结束的Observable的一部分。

我面临的挑战是:如何在正在调用的方法上创建一个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"));
}

但是这会在每次调用方法时创建一个observable而不是我想要的东西,而且它看起来都不是正确的方法。我还读到了使用&#34; Subject&#34;或&#34; AsyncSubject&#34;不是解决问题的正确方法。

1 个答案:

答案 0 :(得分:2)

不使用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,以便正确清理。