public void ExplicitRelease() { int onnext = 0; Exception e = null; bool isCompleted = false; var observable = new OnDemandObservable <int>(); var dispose = observable.AsWeakObservable().Subscribe(new DelegateObserver <int>(i => onnext += i, ex => e = ex, () => { isCompleted = true; })); observable.OnNext(3); onnext.Is(3); observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); // reset values. e = null; isCompleted = false; // unsubscribe dispose.Dispose(); observable.OnNext(6); onnext.Is(3); // it should not be notified. observable.OnError(E); e.IsNull(); observable.OnCompleted(); isCompleted.IsFalse(); }
public void ImplicitReleaseByLostObserver() { int onnext = 0; Exception e = null; bool isCompleted = false; var observable = new OnDemandObservable <int>(); IDisposable disposable = null; WeakReference <IObserver <int> > weak = null; void exec() { var o = new DelegateObserver <int>(i => onnext += i, ex => e = ex, () => { isCompleted = true; }); disposable = observable.AsWeakObservable().Subscribe(o); weak = new WeakReference <IObserver <int> >(o, true); }; // execute inner method. exec(); observable.OnNext(3); onnext.Is(3); observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); // reset values. e = null; isCompleted = false; // Force GC. GC.Collect(0, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(0, GCCollectionMode.Forced); // just to be sure System.Threading.Tasks.Task.Delay(100).Wait(); // It should be notified. Because reference of IDisposable is alive and not unsubscribe automatically, // and so subscription is valid. Reference of IObserver<T> is kept internally, and was not collected by // the garbage collector. observable.OnNext(6); onnext.Is(9); observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); }
public void ImplicitReleaseByLostIDisposable() { int onnext = 0; Exception e = null; bool isCompleted = false; var observable = new OnDemandObservable <int>(); var ovserver = new DelegateObserver <int>(i => onnext += i, ex => e = ex, () => { isCompleted = true; }); WeakReference <IDisposable> weak = null; void exec() { var d = observable.AsWeakObservable().Subscribe(ovserver); weak = new WeakReference <IDisposable>(d, true); }; // execute inner method. exec(); observable.OnNext(3); onnext.Is(3); observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); // reset values. e = null; isCompleted = false; // Force GC. GC.Collect(0, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(0, GCCollectionMode.Forced); // just to be sure. System.Threading.Tasks.Task.Delay(100).Wait(); observable.OnNext(6); onnext.Is(3); // it should not be notified. observable.OnError(E); e.IsNull(); observable.OnCompleted(); isCompleted.IsFalse(); }
public void KeepReferences() { int onnext = 0; Exception e = null; bool isCompleted = false; var observable = new OnDemandObservable <int>(); var observer = new DelegateObserver <int>(i => onnext += i, ex => e = ex, () => { isCompleted = true; }); var dispose = observable.AsWeakObservable().Subscribe(observer); observable.OnNext(3); onnext.Is(3); observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); // reset values. e = null; isCompleted = false; // force GC. GC.Collect(0, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(0, GCCollectionMode.Forced); // just to be sure System.Threading.Tasks.Task.Delay(100).Wait(); observable.OnNext(6); onnext.Is(9); // to be notified observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); }