/// <summary> /// Subscribes to notifications produced by an observable object /// </summary> /// <typeparam name="TSource">The type of notification</typeparam> /// <param name="source">The observable source</param> /// <param name="handleNext">(Optional) An action delegate that will be /// invoked when the next notification is produced by the observable object</param> /// <param name="handleComplete">(Optional) An action delegate that will be /// invoked when all notifications have been produced</param> /// <param name="handleError">(Optional) An action delegate that will be /// invoked when an error notification is produced by the observable object</param> /// <returns>Returns a disposable object representing the subscription which, /// when disposed, will terminate the subscription</returns> public static IDisposable Subscribe <TSource>(this IObservable <TSource> source, Action <TSource> handleNext, Action handleComplete = null, Action <Exception> handleError = null) { var observer = new DelegateObserver <TSource>(handleNext, handleComplete, handleError); return(source.Subscribe(observer)); }
public void CallOnNext() { string test = null; var observer = new DelegateObserver <string>(s => test = s); observer.OnNext(TEST); test.Is(TEST); }
public void executeAsync(object param, DelegateObserver observer) { this.mDelegateObserver = observer; Thread thread = new Thread(doExecute); thread.Start(param); }
public void CallOnCompleted() { string completeMessage = null; var observer = new DelegateObserver <string>(null, onCompleted: () => completeMessage = TEST); observer.OnCompleted(); completeMessage.Is(TEST); }
public void CallOnError() { Exception testExp = null; var observer = new DelegateObserver <string>(null, onError: exception => testExp = exception); observer.OnError(new NotImplementedException(TEST)); testExp.IsInstanceOf <NotImplementedException>(); (testExp as NotImplementedException)?.Message.Is(TEST); }
public void NoSpecifiedDelegates() { var testObservable = new OnDemandObservable <int>(); var observer = new DelegateObserver <int>(); testObservable.Subscribe(observer); testObservable.OnNext(1); testObservable.OnError(new ArgumentException()); testObservable.OnCompleted(); }
public void ConstructorWithParameter() { var subject = new DelegateObserver <int>(); IDisposable exec(IObserver <int> o) { subject.Next += o.OnNext; subject.Error += o.OnError; subject.Completed += o.OnCompleted; return(new DelegateDisposable(() => { subject.Next -= o.OnNext; subject.Error -= o.OnError; subject.Completed -= o.OnCompleted; })); } var observable = new DelegateObservable <int>(exec); int next = 0; Exception exception = null; bool completed = false; var observer = new DelegateObserver <int>(i => next = i, eee => exception = eee, () => completed = true); var disposer = observable.Subscribe(observer); subject.OnNext(3); subject.OnError(new ArgumentNullException(TEST)); subject.OnCompleted(); // assert next.Is(3); exception.IsInstanceOf <ArgumentNullException>(); (exception as ArgumentNullException)?.ParamName.Is(TEST); completed.IsTrue(); next = 0; exception = null; completed = false; // release subscribe. disposer.Dispose(); subject.OnNext(3); subject.OnError(new ArgumentOutOfRangeException(TEST)); subject.OnCompleted(); next.Is(0); exception.IsNull(); completed.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 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.VeryWeakSubscribe(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(); observable.OnNext(6); onnext.Is(3); // it should not be notified. observable.OnError(E); e.IsNull(); observable.OnCompleted(); isCompleted.IsFalse(); }
private static void DelegateSample() { DelegateObserver observer = new DelegateObserver(); // задаём коллбэк одновременно специфицируя и объект, на котором вызывать, и метод, который вызывать. // всё это хранится в инстансе MulticastDelegate DelegateNotifier notifier = new DelegateNotifier(observer.CallbackMethod); // сейчас нотификатор уведомит наблюдателя, вызывая коллбэк. notifier.NotifyAfterTimeout(2000); Console.Read(); // нотификатор ничего не знает о наблюдателе. Мы используем посредника (класс Program), чтобы организовать взаимодействие // наблюдаемого объекта и наблюдателя. }
public void SpecifyFull() { int t = 0; bool completed = false; Exception ee = null; var testObservable = new OnDemandObservable <int>(); var observer = new DelegateObserver <int>(i => t = i, exception => ee = exception, () => completed = true); testObservable.Subscribe(observer); testObservable.OnNext(1); t.Is(1); testObservable.OnError(new Exception()); ee.IsNotNull(); testObservable.OnCompleted(); completed.IsTrue(); }
public void DelegateObserver_Disposed_Does_Not_Send_OnComplete() { int result = -1; var b = new DelegateObserver <int>( i => { }, exception => { }, () => { result = 1; }); b.Dispose(); Assert.True(b.IsDisposed); Assert.Equal(-1, result); }
public void SetNull() { var subject = new DelegateObserver <int>(); IDisposable exec(IObserver <int> o) { subject.Next += o.OnNext; subject.Error += o.OnError; subject.Completed += o.OnCompleted; return(new DelegateDisposable(() => { subject.Next -= o.OnNext; subject.Error -= o.OnError; subject.Completed -= o.OnCompleted; })); } var observable = new DelegateObservable <int>(exec); int next = 0; Exception exception = null; bool completed = false; var observer = new DelegateObserver <int>(i => next = i, eee => exception = eee, () => completed = true); var disposer = observable.Subscribe(observer); // Since it should be related to the subject, it should react even if replacing delegate. observable.DelegateOfSubscribe = null; subject.OnNext(6); next.Is(6); subject.OnError(new ArgumentNullException(TEST)); exception.IsInstanceOf <ArgumentNullException>(); (exception as ArgumentNullException)?.ParamName.Is(TEST); subject.OnCompleted(); completed.IsTrue(); }
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.WeakSubscribe(observer); // observer = null; 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); // it should be notified. observable.OnError(E); e.IsNotNull(); observable.OnCompleted(); isCompleted.IsTrue(); }
public void ManySubscriber() { var subject = new DelegateObserver <int>(); IDisposable exec(IObserver <int> o) { subject.Next += o.OnNext; subject.Error += o.OnError; subject.Completed += o.OnCompleted; return(new DelegateDisposable(() => { subject.Next -= o.OnNext; subject.Error -= o.OnError; subject.Completed -= o.OnCompleted; })); } var observable = new DelegateObservable <int>(); observable.DelegateOfSubscribe = exec; int next1 = 0; Exception exception1 = null; bool completed1 = false; var observer1 = new DelegateObserver <int>(i => next1 = i, eee => exception1 = eee, () => completed1 = true); var disposer1 = observable.Subscribe(observer1); int next2 = 0; Exception exception2 = null; bool completed2 = false; var observer2 = new DelegateObserver <int>(i => next2 = i, eee => exception2 = eee, () => completed2 = true); var disposer2 = observable.Subscribe(observer2); // onNext subject.OnNext(3); next1.Is(3); next2.Is(3); // onError subject.OnError(new ArgumentOutOfRangeException(TEST)); exception1.IsInstanceOf <ArgumentOutOfRangeException>(); (exception1 as ArgumentOutOfRangeException)?.ParamName.Is(TEST); exception2.IsInstanceOf <ArgumentOutOfRangeException>(); (exception2 as ArgumentOutOfRangeException)?.ParamName.Is(TEST); // onComplete subject.OnCompleted(); completed1.IsTrue(); completed2.IsTrue(); // re-initialize next1 = 0; exception1 = null; completed1 = false; next2 = 0; exception2 = null; completed2 = false; // disposing only disposer1. disposer1.Dispose(); subject.OnNext(6); next1.Is(0); next2.Is(6); subject.OnError(new NotSupportedException(TEST)); exception1.IsNull(); // exception2.IsInstanceOf <NotSupportedException>(); (exception2 as NotSupportedException)?.Message.Is(TEST); subject.OnCompleted(); completed1.IsFalse(); completed2.IsTrue(); }