/// <summary> /// Returns an observable that observes all non-perished items added to the collection, now and in the future. /// Items may perish while being observed. /// </summary> public IObservable <Perishable <T> > CurrentAndFutureItems() { return(new AnonymousObservable <Perishable <T> >(observer => { var d = new DisposableLifetime(); EnumerateAndObserve(observer.OnNext, d.Lifetime); return d; })); }
/// <summary>Tracks the number of observed items that have not yet perished, counting up from 0.</summary> /// <param name="observable">The source observable that provides perishable items to be counted.</param> /// <param name="completeWhenSourceCompletes"> /// Determines when the resulting observable completes. /// If true, the resulting observable completes as soon as the source observable completes. /// If false, the resulting observable completes when the observed count is 0 and the source observable has completed. /// </param> public static IObservable <int> ObserveNonPerishedCount <T>(this IObservable <Perishable <T> > observable, bool completeWhenSourceCompletes) { if (observable == null) { throw new ArgumentNullException(nameof(observable)); } return(new AnonymousObservable <int>(observer => { var exposedDisposable = new DisposableLifetime(); var count = 0; var syncRoot = new object(); var isSourceComplete = false; observer.OnNext(0); Action tryComplete = () => { if (isSourceComplete && (completeWhenSourceCompletes || count == 0)) { observer.OnCompleted(); } }; observable.Subscribe( item => { lock (syncRoot) { count += 1; observer.OnNext(count); } item.Lifetime.WhenDead( () => { lock (syncRoot) { // may have finished while acquiring the lock if (exposedDisposable.Lifetime.IsDead) { return; } count -= 1; observer.OnNext(count); tryComplete(); } }, exposedDisposable.Lifetime); }, error => { lock (syncRoot) { exposedDisposable.Dispose(); observer.OnError(error); } }, () => { lock (syncRoot) { isSourceComplete = true; tryComplete(); } }, exposedDisposable.Lifetime); return exposedDisposable; })); }
public void Dispose_ServiceContainer_DisposesDisposableLifeTimeInstances() { var lifetime = new DisposableLifetime(); using (var container = new ServiceContainer()) { container.Register <IFoo, Foo>(lifetime); } Assert.IsTrue(lifetime.IsDisposed); }
public void DisposableLifetime() { var d = new DisposableLifetime(); d.Lifetime.IsMortal.AssertIsTrue(); d.Dispose(); d.Lifetime.IsDead.AssertIsTrue(); InvalidCallbackMaker.AssertCollectedAfter(a => { var r = new DisposableLifetime(); var life = r.Lifetime; life.WhenDead(a); return(life); }); }
public void Dispose_ServiceContainer_DisposesDisposableLifeTimeInstances() { var lifetime = new DisposableLifetime(); using (var container = new ServiceContainer()) { container.Register<IFoo, Foo>(lifetime); } Assert.True(lifetime.IsDisposed); }