2017-05-08 69 views
0

我已經閱讀了這個問題...「默認」訂閱如果在RX模式下(無擴展)無用戶

"Exclusive" and "Default" Subscription Modes in 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可以設置,反之亦然

總之......在EventStream始終如果DefaultSubscriber訂閱可用。通過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 
    } 
} 

回答

0

找到了解決辦法...

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。

因此,我可以添加當沒有外部訂閱加入其中使用默認訂戶(或觀察器)。 如果任何外部觀察者只訂閱外部訂閱者將獲得通知(而不是默認觀察者)。