簡體   English   中英

如果Rx中沒有訂閱者(反應性擴展),則為“默認”訂閱

[英]“Default” subscription if no subscriber in Rx (Reactive Extensions)

我已經讀過這個問題了...

Rx中的“獨家”和“默認”訂閱模式

我的情況非常相似。

我喜歡創造類似的東西...

class Example {
    private stativ readonly Subject<Unit> EventStreamSubject =
        new Subject<Unit>();

    public static IObservable<Unit> EventStream {
        get {
            // TODO
        }
    }

    public static void SetDefault(IObserver<Unit> defaultSubscriber) {
        _defaultSubscriber = defaultSubscriber;
        // TODO
    }
    private static IObserver<Unit> _defaultSubscriber;
}

規則...

  • 只能有一個或沒有DefaultSubscriber
  • 如果EventStream上沒有訂閱者,則使用DefaultSubscriber
  • 如果有任意數量的訂閱者訂閱EventStream,則在處理訂閱之前,DefaultSubscriber不應接收任何元素
  • 可以在另一個訂閱者已經訂閱EventStream之后設置DefaultSubscriber(並且直到最后一次訂閱被使用時才使用),反之亦然

總而言之...如果DefaultSubscriber可用,則始終訂閱EventStream。 由DefaultSubscriber或任何其他外部訂戶(如果沒有DefaultSubscriber,則不由)。

我可以使用Rx中的任何方法來觀察訂閱中的任何更改嗎? 我可以觀察訂閱還是觀察訂閱結束?

與另一個問題的區別是...元素沒有有關應使用哪個訂戶的任何信息。

謝謝你的幫助。

在這里我要運行的代碼...

    static void Main(string[] args)
    {
        var defaultSubscriber = Observer.Create(x => Console.WriteLine("DefaultSubscriber is used"));
        Example.SetDefault(defaultSubscriber);

        Example.EventStreamSubject.OnNext(Unit.Default);

        using (Example.EventStream.Subscribe(x => Console.WriteLine("Subscriber 1 is used")))
        {
            Example.EventStreamSubject.OnNext(Unit.Default);

            using (Example.EventStream.Subscribe(x => Console.WriteLine("Subscriber 1.1 is used")))
            {
                Example.EventStreamSubject.OnNext(Unit.Default);
            }

            Example.EventStreamSubject.OnNext(Unit.Default);
        }

        Example.EventStreamSubject.OnNext(Unit.Default);

        using (Example.EventStream.Subscribe(x => Console.WriteLine("Subscriber 2 is used")))
        {
            using (Example.EventStream.Subscribe(x => Console.WriteLine("Subscriber 2.1 is used")))
            {
                Example.EventStreamSubject.OnNext(Unit.Default);
            }
        }

        Example.EventStreamSubject.OnNext(Unit.Default);

        // expected output:
        //      DefaultSubscriber is used
        //      Subscriber 1 is used
        //      Subscriber 1 is used
        //      Subscriber 1.1 is used
        //      Subscriber 1 is used
        //      DefaultSubscriber is used
        //      Subscriber 2 is used
        //      Subscriber 2.1 is used
        //      DefaultSubscriber is used
    }
}

找到了解決方案...

class Example
{
    internal static readonly Subject<Unit> EventStreamSubject =
        new Subject<Unit>();

    private static readonly Subject<Unit> ExternalEventStreamSubject =
        new Subject<Unit>();

    private static bool _isConnected = false;

    private static void Connect()
    {
        if (!_isConnected)
        {
            EventStreamSubject.Subscribe(ExternalEventStreamSubject);
            _isConnected = true;
        }
    }

    public static IObservable<Unit> EventStream
    {
        get
        {
            Connect();
            return ExternalEventStreamSubject.AsObservable();
        }
    }

    public static void SetDefault(IObserver<Unit> defaultSubscriber)
    {
        if (!Object.ReferenceEquals(_defaultSubscriber, defaultSubscriber))
        {
            _defaultSubscription?.Dispose();

            _defaultSubscriber = defaultSubscriber;

            if (_defaultSubscriber != null)
            {
                _defaultSubscription = EventStreamSubject.
                    Where(x => !ExternalEventStreamSubject.HasObservers).
                    Subscribe(_defaultSubscriber);
            }
        }
    }
    private static IObserver<Unit> _defaultSubscriber;
    private static IDisposable _defaultSubscription;
}

我為外部訂戶使用了另一個“主題”。 如果某些外部觀察者訂閱了EventStream,則該主題的“ HasObservers”屬性為true。

因此,我可以添加一個默認訂戶(或觀察者),該默認訂戶(或觀察者)在未添加任何外部訂閱時使用。 如果有任何外部觀察者訂閱,則只有外部訂閱者會收到通知(不是默認觀察者)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM