Beispiel #1
0
        public void SingleAssignment()
        {
            var d = new SingleAssignmentDisposable();
            d.IsDisposed.IsFalse();
            var id1 = new IdDisp(1);
            var id2 = new IdDisp(2);
            var id3 = new IdDisp(3);

            // dispose first
            d.Dispose();
            d.IsDisposed.IsTrue();

            d.Disposable = id1; id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // normal flow
            d = new SingleAssignmentDisposable();
            id1 = new IdDisp(1);
            id2 = new IdDisp(2);
            id3 = new IdDisp(3);

            d.Disposable = id1; id1.IsDisposed.IsFalse();
            d.Dispose();
            id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // exception flow
            d = new SingleAssignmentDisposable();
            id1 = new IdDisp(1);
            id2 = new IdDisp(2);
            id3 = new IdDisp(3);
            d.Disposable = id1;
            AssertEx.Catch<InvalidOperationException>(() => d.Disposable = id2);

            // null
            d = new SingleAssignmentDisposable();
            id1 = new IdDisp(1);
            d.Disposable = null;
            d.Dispose();
            d.Disposable = null;
        }
Beispiel #2
0
                public IDisposable Run(TParent parent)
                {
                    _active       = false;
                    _running      = false;
                    _queue        = new Queue <System.Reactive.TimeInterval <TSource> >();
                    _hasCompleted = false;
                    _completeAt   = default(TimeSpan);
                    _hasFailed    = false;
                    _exception    = default(Exception);

                    _watch = _scheduler.StartStopwatch();

                    RunCore(parent);

                    var sourceSubscription = new SingleAssignmentDisposable();

                    _sourceSubscription           = sourceSubscription;
                    sourceSubscription.Disposable = parent._source.SubscribeSafe(this);

                    return(StableCompositeDisposable.Create(_sourceSubscription, _cancelable));
                }
Beispiel #3
0
            public override void OnNext(TSource value)
            {
                IObservable <TResult> nextObservable;

                try
                {
                    nextObservable = parent.selectorWithIndex(value, index++);
                }
                catch (Exception ex)
                {
                    try { observer.OnError(ex); } finally { Dispose(); };
                    return;
                }

                var disposable = new SingleAssignmentDisposable();

                collectionDisposable.Add(disposable);
                var collectionObserver = new SelectMany(this, disposable);

                disposable.Disposable = nextObservable.Subscribe(collectionObserver);
            }
Beispiel #4
0
            public IDisposable Run()
            {
                leftSubscription  = new SingleAssignmentDisposable();
                rightSubscription = new SingleAssignmentDisposable();
                var d = StableCompositeDisposable.Create(leftSubscription, rightSubscription);

                var left = new Amb();

                left.targetDisposable = d;
                left.targetObserver   = new AmbDecisionObserver(this, AmbState.Left, rightSubscription, left);

                var right = new Amb();

                right.targetDisposable = d;
                right.targetObserver   = new AmbDecisionObserver(this, AmbState.Right, leftSubscription, right);

                leftSubscription.Disposable  = parent.source.Subscribe(left);
                rightSubscription.Disposable = parent.second.Subscribe(right);

                return(d);
            }
Beispiel #5
0
        /// <summary>
        /// Submit the drain task via the appropriate scheduler if
        /// there is no drain currently running (wip > 0).
        /// </summary>
        private void Schedule()
        {
            if (Interlocked.Increment(ref _wip) == 1)
            {
                var newTask = new SingleAssignmentDisposable();

                if (Disposable.TrySetMultiple(ref _task, newTask))
                {
                    newTask.Disposable = _scheduler.Schedule(this, DrainShortRunningFunc);
                }

                // If there was a cancellation, clear the queue
                // of items. This doesn't have to be inside the
                // wip != 0 (exclusive) mode as the queue
                // is of a multi-consumer type.
                if (Volatile.Read(ref _disposed))
                {
                    Clear(_queue);
                }
            }
        }
Beispiel #6
0
                private void CreateTimer()
                {
                    var m = new SingleAssignmentDisposable();

                    Disposable.TrySetSerial(ref _timerSerial, m);

                    var isSpan  = false;
                    var isShift = false;

                    if (_nextSpan == _nextShift)
                    {
                        isSpan  = true;
                        isShift = true;
                    }
                    else if (_nextSpan < _nextShift)
                    {
                        isSpan = true;
                    }
                    else
                    {
                        isShift = true;
                    }

                    var newTotalTime = isSpan ? _nextSpan : _nextShift;
                    var ts           = newTotalTime - _totalTime;

                    _totalTime = newTotalTime;

                    if (isSpan)
                    {
                        _nextSpan += _timeShift;
                    }

                    if (isShift)
                    {
                        _nextShift += _timeShift;
                    }

                    m.Disposable = _scheduler.ScheduleAction((@this: this, isSpan, isShift), ts, tuple => [email protected](tuple.isSpan, tuple.isShift));
                }
        public void SchedulePeriodic_Nested()
        {
            using (WinFormsTestUtils.RunTest(out var lbl))
            {
                var evt = new ManualResetEvent(false);

                var id = Thread.CurrentThread.ManagedThreadId;

                var sch = new ControlScheduler(lbl);

                sch.Schedule(() =>
                {
                    lbl.Text = "Okay";

                    var d = new SingleAssignmentDisposable();

                    d.Disposable = sch.SchedulePeriodic(1, TimeSpan.FromSeconds(0.1), n =>
                    {
                        lbl.Text = "Okay " + n;
                        Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);

                        if (n == 3)
                        {
                            d.Dispose();

                            sch.Schedule(TimeSpan.FromSeconds(0.2), () =>
                            {
                                Assert.Equal("Okay 3", lbl.Text);
                                Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
                                evt.Set();
                            });
                        }

                        return(n + 1);
                    });
                });

                evt.WaitOne();
            }
        }
Beispiel #8
0
        public ReactiveDerivedCollectionFromObservable(
            IObservable <T> observable,
            TimeSpan?withDelay         = null,
            Action <Exception> onError = null,
            IScheduler scheduler       = null)
        {
            scheduler = scheduler ?? RxApp.MainThreadScheduler;
            _inner    = new SingleAssignmentDisposable();

            onError = onError ?? (ex => RxApp.DefaultExceptionHandler.OnNext(ex));
            if (withDelay == null)
            {
                _inner.Disposable = observable.ObserveOn(scheduler).Subscribe(InternalAdd, onError);
                return;
            }

            // On a timer, dequeue items from queue if they are available
            var queue      = new Queue <T>();
            var disconnect = Observable.Timer(withDelay.Value, withDelay.Value, scheduler)
                             .Subscribe(_ =>
            {
                if (queue.Count > 0)
                {
                    InternalAdd(queue.Dequeue());
                }
            });

            _inner.Disposable = disconnect;

            // When new items come in from the observable, stuff them in the queue.
            observable.ObserveOn(scheduler).Subscribe(queue.Enqueue, onError);

            // This is a bit clever - keep a running count of the items actually
            // added and compare them to the final count of items provided by the
            // Observable. Combine the two values, and when they're equal,
            // disconnect the timer
            ItemsAdded.Scan(0, (acc, _) => acc + 1).Zip(
                observable.Aggregate(0, (acc, _) => acc + 1),
                (l, r) => l == r).Where(x => x).Subscribe(_ => disconnect.Dispose());
        }
Beispiel #9
0
        public IDisposable Subscribe(
            IMessagingSession messagingSession,
            string destination,
            Action <BinaryMessage, Action <bool> > callback,
            string messageType,
            int priority)
        {
            if (m_IsDisposing)
            {
                throw new ObjectDisposedException("ProcessingGroup " + Name);
            }

            var taskFactory  = m_SchedulingStrategy.GetTaskFactory(priority);
            var subscription = new SingleAssignmentDisposable();

            subscription.Disposable = messagingSession.Subscribe(
                destination,
                (message, ack) =>
            {
                Interlocked.Increment(ref m_TasksInProgress);
                taskFactory.StartNew(() =>
                {
                    Interlocked.Increment(ref m_ReceivedMessages);
                    //if subscription is disposed unack message immediately
                    if (subscription.IsDisposed)
                    {
                        ack(false);
                    }
                    else
                    {
                        callback(message, ack);
                        Interlocked.Increment(ref m_ProcessedMessages);
                    }
                    Interlocked.Decrement(ref m_TasksInProgress);
                },
                                     TaskCreationOptions.HideScheduler);
            },
                messageType);
            return(subscription);
        }
Beispiel #10
0
            public IDisposable SchedulePeriodic <TState>(TState state, TimeSpan period, Func <TState, TState> action)
            {
                var failed = false;

                var d = new SingleAssignmentDisposable();

                d.Disposable = _scheduler.SchedulePeriodic(state, period, state_ =>
                {
                    //
                    // Cancellation may not be granted immediately; prevent from running user
                    // code in that case. Periodic schedulers are assumed to introduce some
                    // degree of concurrency, so we should return from the SchedulePeriodic
                    // call eventually, allowing the d.Dispose() call in the catch block to
                    // take effect.
                    //
                    if (failed)
                    {
                        return(default(TState));
                    }

                    try
                    {
                        return(action(state_));
                    }
                    catch (TException exception)
                    {
                        failed = true;

                        if (!_handler(exception))
                        {
                            throw;
                        }

                        d.Dispose();
                        return(default(TState));
                    }
                });

                return(d);
            }
Beispiel #11
0
 public static IObservable <TSource> SubscribeOn <TSource>(
     this IObservable <TSource> source,
     bool doNotScheduleDisposal,
     IScheduler scheduler)
 {
     if (!doNotScheduleDisposal)
     {
         return(source.SubscribeOn(scheduler));
     }
     return(Observable.Create <TSource>(observer =>
     {
         // Implementation is based on that of the native SubscribeOn operator in Rx
         var s = new SingleAssignmentDisposable();
         var d = new SerialDisposable();
         d.Disposable = s;
         s.Disposable = scheduler.Schedule(() =>
         {
             d.Disposable = source.SubscribeSafe(observer);
         });
         return d;
     }));
 }
        private static void AttachPaginator(IPaginator paginator, DataGrid dataGrid)
        {
            var subscription = new SingleAssignmentDisposable();

            SetPaginatorSubscription(dataGrid, subscription);

            var onPropertyChanged =
                new PropertyChangedEventHandler((sender, e) => UpdateByPaginator(dataGrid));

            dataGrid.ItemsSource       = paginator.CreateReactiveList();
            dataGrid.Sorting          += OnDataGridSorting;
            paginator.PropertyChanged += onPropertyChanged;

            subscription.Disposable = Disposable.Create(() =>
            {
                dataGrid.ItemsSource       = Array.Empty <object>();
                dataGrid.Sorting          -= OnDataGridSorting;
                paginator.PropertyChanged -= onPropertyChanged;
            });

            UpdateByPaginator(dataGrid);
        }
            public IDisposable Subscribe(IObserver <TResult> observer)
            {
                observers.Add(observer);
                SingleAssignmentDisposable dis = null;
                bool wasConnected = connected;
                var  coll         = disposables;        // this is used to detach field reference at disposal (the field might be already null).

                if (wasConnected)
                {
                    dis            = new SingleAssignmentDisposable();
                    dis.Disposable = sub.Subscribe(observer);
                    coll.Add(dis);
                }
                return(Disposable.Create(() => {
                    observers.Remove(observer);
                    if (wasConnected)                       // note: local variable. If it was not added, then do not add it.
                    {
                        coll.Remove(dis);
                        dis.Dispose();
                    }
                }));
            }
Beispiel #14
0
        private IDisposable ScheduleOnDispatcherNow <TState>(TState state, Func <IScheduler, TState, IDisposable> action)
        {
            try
            {
                Interlocked.CompareExchange(ref _dispatcher, CoreApplication.Views.FirstOrDefault()?.Dispatcher, null);
            }
            catch (Exception ex)
            {
                // Ignore
            }

            if (_dispatcher == null || _dispatcher.HasThreadAccess)
            {
                return(action(this, state));
            }

            var d = new SingleAssignmentDisposable();

            var dispatchResult = _dispatcher.RunAsync(
                Priority,
                () =>
            {
                if (!d.IsDisposed)
                {
                    try
                    {
                        d.Disposable = action(this, state);
                    }
                    catch (Exception ex)
                    {
                        RaiseUnhandledException(ex);
                    }
                }
            });

            return(StableCompositeDisposable.Create(
                       d,
                       Disposable.Create(() => dispatchResult.Cancel())));
        }
Beispiel #15
0
        /// <summary>
        /// Schedules an action to be executed.
        /// </summary>
        /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
        /// <param name="state">State passed to the action to be executed.</param>
        /// <param name="action">Action to be executed.</param>
        /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
        public override IDisposable Schedule <TState>(TState state, Func <IScheduler, TState, IDisposable> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var d = new SingleAssignmentDisposable();

            var cancel = s_cal.QueueUserWorkItem(_ =>
            {
                if (!d.IsDisposed)
                {
                    d.Disposable = action(this, state);
                }
            }, null);

            return(StableCompositeDisposable.Create(
                       d,
                       cancel
                       ));
        }
Beispiel #16
0
                private void CreateWindowClose()
                {
                    var windowClose = default(IObservable <TWindowClosing>);

                    try
                    {
                        windowClose = _windowClosingSelector();
                    }
                    catch (Exception exception)
                    {
                        lock (_gate)
                        {
                            ForwardOnError(exception);
                        }
                        return;
                    }

                    var closingSubscription = new SingleAssignmentDisposable();

                    _m.Disposable = closingSubscription;
                    closingSubscription.Disposable = windowClose.SubscribeSafe(new WindowClosingObserver(this, closingSubscription));
                }
Beispiel #17
0
        private static IDisposable InvokeAsync <TState>(IScheduler self, TState s, Func <IScheduler, TState, CancellationToken, Task <IDisposable> > action)
        {
            var c = new CancellationDisposable();
            var d = new SingleAssignmentDisposable();

            action(new CancelableScheduler(self, c.Token), s, c.Token).ContinueWith(t =>
            {
                if (t.IsCanceled)
                {
                    return;
                }

                if (t.Exception != null)
                {
                    t.Exception.Handle(e => e is OperationCanceledException);
                }

                d.Disposable = t.Result;
            }, TaskContinuationOptions.ExecuteSynchronously);

            return(StableCompositeDisposable.Create(c, d));
        }
        public static void AreElementsEqual <T> (IObservable <T> expected, IObservable <T> actual, string message)
        {
            if (expected == null)
            {
                if (actual != null)
                {
                    throw new ArgumentNullException("expected");
                }
                else
                {
                    return;
                }
            }

            int ie = 0, ia = 0, endE = 0, endA = 0;
            var iex    = expected.Select(e => new Indexed <T> (ie++, e)).Finally(() => endE = ie);
            var iac    = actual.Select(e => new Indexed <T> (ia++, e)).Finally(() => endA = ia);
            var source = iex.Zip(iac, (e, a) => { Assert.AreEqual(e.Value, a.Value, String.Format("{0} (Items differ at index {1})", message, e.Index)); return(Unit.Default); });
            var dis    = new SingleAssignmentDisposable();

            dis.Disposable = source.Finally <Unit> (() => dis.Dispose()).Subscribe(v => {}, () => Assert.AreEqual(endE, endA, String.Format("{0} (Items counts differ: expected {1} but got {2})", endE, endA)));
        }
Beispiel #19
0
        /// <summary>
        /// Schedules an action to be executed on the dispatcher.
        /// </summary>
        /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
        /// <param name="state">State passed to the action to be executed.</param>
        /// <param name="action">Action to be executed.</param>
        /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
        public override IDisposable Schedule <TState>(TState state, Func <IScheduler, TState, IDisposable> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var d = new SingleAssignmentDisposable();

            Dispatcher.BeginInvoke(
                new Action(() =>
            {
                if (!d.IsDisposed)
                {
                    d.Disposable = action(this, state);
                }
            }),
                Priority
                );

            return(d);
        }
        public void SchedulePeriodic_Nested()
        {
            var evt = new ManualResetEvent(false);

            var id = Thread.CurrentThread.ManagedThreadId;

            var lbl = CreateLabel();
            var sch = new ControlScheduler(lbl);

            sch.Schedule(() =>
            {
                lbl.Text = "Okay";

                var d = new SingleAssignmentDisposable();

                d.Disposable = sch.SchedulePeriodic(1, TimeSpan.FromSeconds(0.1), n =>
                {
                    lbl.Text = "Okay " + n;
                    Assert.AreNotEqual(id, Thread.CurrentThread.ManagedThreadId);

                    if (n == 3)
                    {
                        d.Dispose();

                        sch.Schedule(TimeSpan.FromSeconds(0.2), () =>
                        {
                            Assert.AreEqual("Okay 3", lbl.Text);
                            Assert.AreNotEqual(id, Thread.CurrentThread.ManagedThreadId);
                            evt.Set();
                        });
                    }

                    return n + 1;
                });
            });

            evt.WaitOne();
            Application.Exit();
        }
Beispiel #21
0
            public IDisposable Run()
            {
                _scheduler = _parent._scheduler;

                _cancelable = new SerialDisposable();

                _gate         = new object();
                _active       = false;
                _running      = false;
                _queue        = new Queue <System.Reactive.TimeInterval <TSource> >();
                _hasCompleted = false;
                _completeAt   = default(TimeSpan);
                _hasFailed    = false;
                _exception    = default(Exception);

                _watch = _scheduler.StartStopwatch();

                if (_parent._dueTimeA.HasValue)
                {
                    _ready = false;

                    var dueTimeA = _parent._dueTimeA.Value;
                    _cancelable.Disposable = _scheduler.Schedule(dueTimeA, Start);
                }
                else
                {
                    _ready = true;

                    var dueTimeR = _parent._dueTimeR.Value;
                    _delay = Scheduler.Normalize(dueTimeR);
                }

                var sourceSubscription = new SingleAssignmentDisposable();

                _sourceSubscription           = sourceSubscription;
                sourceSubscription.Disposable = _parent._source.SubscribeSafe(this);

                return(new CompositeDisposable(_sourceSubscription, _cancelable));
            }
Beispiel #22
0
        public virtual IObservable <bool> EstablishEncryptionAsync()
        {
            ValidateDisposed();

            var future             = new AsyncSubject <bool>();
            var watchStatusChanged = new SingleAssignmentDisposable();

            watchStatusChanged.Disposable = this.ObserveStatusChanged().Subscribe(x =>
            {
                if (x == StatusCode.EncryptionFailedToEstablish)
                {
                    watchStatusChanged.Dispose();
                    future.OnError(new EncryptionFailedToEstablishException());
                }

                if (x == StatusCode.EncryptionEstablished)
                {
                    watchStatusChanged.Dispose();

                    future.OnNext(true);
                    future.OnCompleted();
                }
            });

            if (this.EstablishEncryption())
            {
                return(future.Timeout(Timeout).Catch((Exception ex) =>
                {
                    watchStatusChanged.Dispose();
                    this.Disconnect();
                    return Observable.Throw <bool>(ex);
                }));
            }
            else
            {
                watchStatusChanged.Dispose();
                return(Observable.Return(false));
            }
        }
Beispiel #23
0
                private void CreateBufferClose()
                {
                    var bufferClose = default(IObservable <TBufferClosing>);

                    try
                    {
                        bufferClose = _bufferClosingSelector();
                    }
                    catch (Exception exception)
                    {
                        lock (_gate)
                        {
                            ForwardOnError(exception);
                        }
                        return;
                    }

                    var closingSubscription = new SingleAssignmentDisposable();

                    Disposable.TrySetSerial(ref _bufferClosingSerialDisposable, closingSubscription);
                    closingSubscription.Disposable = bufferClose.SubscribeSafe(new BufferClosingObserver(this, closingSubscription));
                }
Beispiel #24
0
            public override IDisposable Schedule <TState>(TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action)
            {
                if (action == null)
                {
                    throw new ArgumentNullException("action");
                }

                if (dueTime.Ticks <= 0)
                {
                    return(Schedule <TState>(state, action));
                }

                var timer = ConcurrencyAbstractionLayer.Current.StartStopwatch();

                var m = new SingleAssignmentDisposable();

                if (asyncLock == null)
                {
                    asyncLock = new AsyncLock();
                }

                asyncLock.Wait(() =>
                {
                    if (!m.IsDisposed)
                    {
                        var sleep = dueTime - timer.Elapsed;
                        if (sleep.Ticks > 0)
                        {
                            ConcurrencyAbstractionLayer.Current.Sleep(sleep);
                        }
                        if (!m.IsDisposed)
                        {
                            m.Disposable = action(this, state);
                        }
                    }
                });

                return(m);
            }
Beispiel #25
0
            public override void OnError(Exception error)
            {
                TException val = error as TException;

                if (val != null)
                {
                    UniRx.IObservable <T> observable;
                    try
                    {
                        observable = ((!(parent.errorHandler == new Func <TException, UniRx.IObservable <T> >(Stubs.CatchIgnore <T>))) ? parent.errorHandler(val) : Observable.Empty <T>());
                    }
                    catch (Exception error2)
                    {
                        try
                        {
                            observer.OnError(error2);
                        }
                        finally
                        {
                            Dispose();
                        }
                        return;
                    }
                    SingleAssignmentDisposable singleAssignmentDisposable = new SingleAssignmentDisposable();
                    serialDisposable.Disposable           = singleAssignmentDisposable;
                    singleAssignmentDisposable.Disposable = observable.Subscribe(observer);
                }
                else
                {
                    try
                    {
                        observer.OnError(error);
                    }
                    finally
                    {
                        Dispose();
                    }
                }
            }
        /// <summary>
        /// Schedules an action to be executed.
        /// </summary>
        /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
        /// <param name="state">State passed to the action to be executed.</param>
        /// <param name="action">Action to be executed.</param>
        /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
        public override IDisposable Schedule <TState>(TState state, Func <IScheduler, TState, IDisposable> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var d = new SingleAssignmentDisposable();

            var res = global::Windows.System.Threading.ThreadPool.RunAsync(iaa =>
            {
                if (!d.IsDisposed)
                {
                    d.Disposable = action(this, state);
                }
            }, Priority, Options);

            return(new CompositeDisposable(
                       d,
                       Disposable.Create(res.Cancel)
                       ));
        }
Beispiel #27
0
        public void SchedulePeriodic()
        {
            using (DispatcherHelpers.RunTest(out var disp))
            {
                var evt = new ManualResetEvent(false);

                var id = Thread.CurrentThread.ManagedThreadId;

                var sch = new DispatcherScheduler(disp);

                var d = new SingleAssignmentDisposable();

                d.Disposable = sch.SchedulePeriodic(1, TimeSpan.FromSeconds(0.1), n =>
                {
                    Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);

                    if (n == 3)
                    {
                        d.Dispose();

                        sch.Schedule(TimeSpan.FromSeconds(0.2), () =>
                        {
                            Assert.NotEqual(id, Thread.CurrentThread.ManagedThreadId);
                            evt.Set();
                        });
                    }

                    if (n > 3)
                    {
                        Assert.True(false);
                    }

                    return(n + 1);
                });

                evt.WaitOne();
            }
        }
        protected void Subscribe(DuplexCallbackId id)
        {
            IObservableDuplexCallback observable;

            if (!obsevableCallbacks.TryGetValue(id.ClientId, out observable))
            {
                throw new InvalidOperationException(Errors.ProtocolInvalidDuplexId);
            }

#if TRACE
            var sourceId = GetSourceId(id);

            Log.Subscribing(observable.Name, false, true, sourceId, LogMessages.Received);
#endif

            var subscription = new SingleAssignmentDisposable();

            var subscriptionId = RegisterSubscription(new NamedDisposable(observable.Name, subscription));

            try
            {
                subscription.Disposable = observable.Subscribe(
                    value => SendOnNext(observable.Name, id, value),
                    ex => SendOnError(observable.Name, id, ExceptionDispatchInfo.Capture(ex)),
                    () => SendOnCompleted(observable.Name, id));
            }
            catch (Exception ex)
            {
                SendOnError(observable.Name, id, ExceptionDispatchInfo.Capture(ex));
                return;
            }

#if TRACE
            Log.Subscribed(observable.Name, false, true, sourceId, LogMessages.Sending);
#endif

            SendSubscribeResponse(id, subscriptionId);
        }
Beispiel #29
0
            public IDisposable Run()
            {
                var srcs = _parent._sources.ToArray();

                var N = srcs.Length;

                _queues = new Queue <TSource> [N];
                for (int i = 0; i < N; i++)
                {
                    _queues[i] = new Queue <TSource>();
                }

                _isDone = new bool[N];

                _subscriptions = new SingleAssignmentDisposable[N];

                _gate = new object();

                for (int i = 0; i < N; i++)
                {
                    var j = i;

                    var d = new SingleAssignmentDisposable();
                    _subscriptions[j] = d;

                    var o = new SourceObserver(this, j);
                    d.Disposable = srcs[j].SubscribeSafe(o);
                }

                return(new CompositeDisposable(_subscriptions)
                {
                    Disposable.Create(() => { foreach (var q in _queues)
                                              {
                                                  q.Clear();
                                              }
                                      })
                });
            }
        public void Error()
        {
            var resource = new SingleAssignmentDisposable();

            var before = -1;
            var after  = -1;

            var source = CompletableSource.Create(e =>
            {
                e.SetResource(resource);
                before = e.IsDisposed() ? 1 : 0;
                e.OnError(new InvalidOperationException());
                after = e.IsDisposed() ? 1 : 0;
            });

            source.Test()
            .AssertFailure(typeof(InvalidOperationException));

            Assert.AreEqual(0, before);
            Assert.AreEqual(1, after);

            Assert.True(resource.IsDisposed());
        }
        public void Basic()
        {
            var resource = new SingleAssignmentDisposable();

            var before = -1;
            var after  = -1;

            var source = CompletableSource.Create(e =>
            {
                e.SetResource(resource);
                before = e.IsDisposed() ? 1 : 0;
                e.OnCompleted();
                after = e.IsDisposed() ? 1 : 0;
            });

            source.Test()
            .AssertResult();

            Assert.AreEqual(0, before);
            Assert.AreEqual(1, after);

            Assert.True(resource.IsDisposed());
        }
        public virtual IObservable<bool> ConnectAsync(string serverAddress, string applicationName)
        {
            ValidateDisposed();

            var future = new AsyncSubject<bool>();
            var watchStatusChanged = new SingleAssignmentDisposable();
            watchStatusChanged.Disposable = this.ObserveStatusChanged().Subscribe(x =>
            {
                if (x == StatusCode.ExceptionOnConnect)
                {
                    watchStatusChanged.Dispose();
                    future.OnError(new ConnectionFailedException(serverAddress, applicationName));
                }

                if (x == StatusCode.Connect)
                {
                    watchStatusChanged.Dispose();

                    future.OnNext(true);
                    future.OnCompleted();
                }
            });

            if (this.Connect(serverAddress, applicationName))
            {
                this.LastConnectServerAddress = serverAddress;
                this.LastConnectApplicationName = applicationName;

                return future.Timeout(Timeout).Catch((Exception ex) =>
                {
                    watchStatusChanged.Dispose();
                    this.Disconnect();
                    return Observable.Throw<bool>(ex);
                });
            }
            else
            {
                watchStatusChanged.Dispose();
                return Observable.Return(false);
            }
        }
        public virtual IObservable<bool> EstablishEncryptionAsync()
        {
            ValidateDisposed();

            var future = new AsyncSubject<bool>();
            var watchStatusChanged = new SingleAssignmentDisposable();
            watchStatusChanged.Disposable = this.ObserveStatusChanged().Subscribe(x =>
            {
                if (x == StatusCode.EncryptionFailedToEstablish)
                {
                    watchStatusChanged.Dispose();
                    future.OnError(new EncryptionFailedToEstablishException());
                }

                if (x == StatusCode.EncryptionEstablished)
                {
                    watchStatusChanged.Dispose();

                    future.OnNext(true);
                    future.OnCompleted();
                }
            });

            if (this.EstablishEncryption())
            {
                return future.Timeout(Timeout).Catch((Exception ex) =>
                {
                    watchStatusChanged.Dispose();
                    this.Disconnect();
                    return Observable.Throw<bool>(ex);
                });
            }
            else
            {
                watchStatusChanged.Dispose();
                return Observable.Return(false);
            }
        }