代码之家  ›  专栏  ›  技术社区  ›  Gautam T Goudar

在方法上创建可观察的

  •  5
  • Gautam T Goudar  · 技术社区  · 6 年前

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

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

    我面临的挑战是:如何在被调用的方法上创建一个可观察的?下面是我的示例代码。

    //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 回复  |  直到 6 年前
        1
  •  2
  •   Enigmativity    6 年前

    不使用规则 Subject 更多的是一个没有很好表达的指导方针。

    一般来说,如果你在使用主题 在内部 一条可以观察到的管道,那么你很可能做了一些错误的事情——这应该避免。

    如果你用的是 主题 作为可观测数据的来源 正确封装 主题 你把它弄混了,那你就没事了。所以这通常意味着使用 private 只有您的代码才能访问的字段(因此没有人可以调用 .OnCompleted() 接电话和打电话 .AsObservable() 这样就没有人能把你的可观测数据 主题 .

    在您的情况下,您直接订阅,所以不 .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));
    }
    

    现在,如果你仍然想避免 主题 然后您可以选择这样做:

    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));
    }
    

    在我看来 主题 给你更好的控制,更容易设置。

    无论如何,您可能应该保留订阅 IDisposable 这样你就可以好好清理了。