The best way to call OnCompleted on all subscribers to a bunch of handed out IObservables

Beantwortet The best way to call OnCompleted on all subscribers to a bunch of handed out IObservables

  • 2012年4月27日 23:59
     
     

    I have an object, with methods and properties returning a lot of different IObservables to the clients.

    When Dispose gets called on that object, I want to 'somehow' cause OnCompleted to be called on all subscribers.

    Some methods of achieving that, that come to my mind, are either too laborious or smell of unnecessary complexity, so I am seeking help from the community.

    Has anybody encountered and solved this pattern in an elegant way?

    Thanks!

    Edit: 

    Let me qualify that more: I certainly don't want to have to devise some mechanism by which some flag will be set somewhere and then all producers would eventually read it as a signal and call OnCompleted themselves. Some data producers may need time to be killed, but I want them to be disconnected from observers as soon as Dispose gets called on the 'master' object. I was looking at TakeWhile operator but I have no experience with it yet and it may be an overkill.
    • 已编辑 Tonko 2012年4月28日 0:16
    •  

全部回复

  • 2012年4月28日 9:37
     
     已答复 包含代码

    Hi,

    You could use a Subject<T> to represent stateful, asynchronous disposal and then apply TakeUntil to every observable.

    class SeveralObservables : IDisposable
    {
    	public IObservable<int> First
    	{
    		get
    		{
    			return Elsewhere.GetFirstObservable().TakeUntil(disposed);
    		}
    	}
    
    	public IObservable<int> Second
    	{
    		get
    		{
    			return Elsewhere.GetSecondObservable().TakeUntil(disposed);
    		}
    	}
    
    	public IObservable<int> Third
    	{
    		get
    		{
    			return Elsewhere.GetThirdObservable().TakeUntil(disposed);
    		}
    	}
    
    	private readonly Subject<Unit> disposed = new Subject<Unit>();
    
    	public void Dispose()
    	{
    		disposed.OnNext(Unit.Default);
    		disposed.OnCompleted();
    	}
    }

    - Dave


    http://davesexton.com/blog

    • 已标记为答案 Tonko 2012年5月11日 20:52
    •  
  • 2012年4月29日 19:33
     
     

    Elegant enough for me, thanks Dave!

    Let me do some tests re possible performance degradation before marking it as answer. 

  • 2012年4月30日 12:21
     
     

    Hi, 

    Note that you can use ReplaySubject(2) instead of Subject to ensure that later subscriptions see OnCompleted as soon as possible.

    - Dave


    http://davesexton.com/blog