Пример #1
0
        /// <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);
        }
Пример #3
0
        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();
        }
Пример #8
0
        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();
        }
Пример #9
0
        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();
        }
Пример #10
0
        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();
        }
Пример #12
0
        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();
        }
Пример #14
0
        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();
        }