Exemple #1
0
            // in timer
            void OnNext()
            {
                lock (gate) {
                    if (isFinished)
                    {
                        return;
                    }

                    isFinished = true;
                }

                sourceSubscription.Dispose();
                try { observer.OnError(new TimeoutException()); } finally { Dispose(); }
            }
Exemple #2
0
            public void OnError(Exception error)
            {
                lock (Gate)
                {
                    outerIsStopped = true;
                    outerError     = error;

                    if (!innerIsStopped)
                    {
                        // Wait until it stops.
                        // NOTE: If we would like to stop the inner immediately,
                        // we'll need a lock for each value of it and ignore the error of it.
                    }
                    else if (innerError != null)
                    {
                        // Already notified an error.
                    }
                    else
                    {
                        observer.OnError(error);
                        subscription.Dispose();
                    }
                }
            }
Exemple #3
0
            public void OnCompleted()
            {
                _subscription.Dispose();

                var longRunning = _parent._loopScheduler.AsLongRunning();

                if (longRunning != null)
                {
                    _loop.Disposable = longRunning.ScheduleLongRunning(Loop);
                }
                else
                {
                    _loop.Disposable = _parent._loopScheduler.Schedule(LoopRec);
                }
            }
Exemple #4
0
        public FSharpAsync <Unit> Run()
        {
            return(Apm.Create <Unit>((success, error) => {
                var disp = new SingleAssignmentDisposable();
                Action <Action> CompleteWith = cont => {
                    cont();
                    disp.Dispose();
                };

                var model = new InfoViewModel(message);
                model.close = () => { success(null); };
                var view = new InfoView(model);
                disp.Disposable = presenter.ShowView(view);
                return disp;
            }));
        }
Exemple #5
0
        public void ErrorSubscription()
        {
            bool done          = false;
            bool shouldNotPass = false;
            var  o             = Observable.Create <int> (observer => { try { throw new Exception(); return(Disposable.Empty); } finally { done = true; } });
            var  dis           = new SingleAssignmentDisposable();

            try {
                dis.Disposable = o.SubscribeOn(Scheduler.ThreadPool).Subscribe(v => {}, ex => shouldNotPass = true);
            } finally {
                dis.Dispose();
            }
            SpinWait.SpinUntil(() => done, 1000);
            Assert.IsTrue(done, "#1");
            Assert.IsFalse(shouldNotPass, "#2");
            // the exception does not occur in *this* thread, so it passes here.
        }
Exemple #6
0
        public IDisposable Schedule <TState>(TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action)
        {
            SingleAssignmentDisposable disposable = new SingleAssignmentDisposable();
            var timer = new Timer(t => {
                m_actionFlow.Invoke(() => {
                    if (!disposable.IsDisposed)
                    {
                        disposable.Disposable = action(this, state);
                    }
                });
            });

            timer.Change(dueTime, TimeSpan.FromMilliseconds(-1));
            return(Disposable.Create(() => {
                disposable.Dispose();
                timer.Dispose();
            }));
        }
        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;
        }
Exemple #8
0
        public IDisposable Subscribe(IObserver <T> observer)
        {
            var t = 0f;

            var source             = _sourceSelector();
            var velocity           = _velocitySelector();
            var oldProjectedTarget = Project(source, velocity, _duration);

            var disposable = new SingleAssignmentDisposable();

            disposable.Disposable = Observable.EveryUpdate().Subscribe(_ =>
            {
                t += Time.deltaTime / _duration;
                bool isCompleted = false;
                if (t >= 0.99999f)
                {
                    t           = 1f;
                    isCompleted = true;
                }

                try
                {
                    var oldProjectedValue = Lerp(t, source, oldProjectedTarget);
                    var desiredValue      = Lerp(t.Ease(_easer), source, _target);
                    var actualValue       = Lerp(t, oldProjectedValue, desiredValue);

                    observer.OnNext(actualValue);

                    if (isCompleted)
                    {
                        observer.OnCompleted();
                    }
                }
                finally
                {
                    if (isCompleted)
                    {
                        disposable.Dispose();
                    }
                }
            });

            return(disposable);
        }
Exemple #9
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;
        }
                public override void OnCompleted()
                {
                    _subscription.Dispose();

                    var now = _watch.Elapsed;

                    Trim(now);

                    var longRunning = _parent._loopScheduler.AsLongRunning();

                    if (longRunning != null)
                    {
                        _loop.Disposable = longRunning.ScheduleLongRunning(Loop);
                    }
                    else
                    {
                        _loop.Disposable = _parent._loopScheduler.Schedule(LoopRec);
                    }
                }
Exemple #11
0
        /// <summary>
        /// Awaits a task on the specified scheduler, without providing a result.
        /// </summary>
        /// <returns>A task that will complete when the work has completed.</returns>
        public static Task Run(this IScheduler source, Action action, CancellationToken ct)
        {
            var completion = new FastTaskCompletionSource <Unit>();

            var disposable = new SingleAssignmentDisposable();
            var ctr        = default(CancellationTokenRegistration);

            if (ct.CanBeCanceled)
            {
                ctr = ct.Register(() =>
                {
                    completion.TrySetCanceled();
                    disposable.Dispose();
                });
            }

            disposable.Disposable = source.Schedule(
                () =>
            {
                if (disposable.IsDisposed)
                {
                    return;                             // CT canceled
                }

                try
                {
                    action();
                    completion.TrySetResult(Unit.Default);
                }
                catch (Exception e)
                {
                    completion.TrySetException(e);
                }
                finally
                {
                    ctr.Dispose();
                }
            }
                );

            return(completion.Task);
        }
Exemple #12
0
        /// <summary>
        /// Awaits a task execution on the specified scheduler, providing the result.
        /// </summary>
        /// <returns>A task that will provide the result of the execution.</returns>
        public static Task <T> Run <T>(this IScheduler source, Func <T> func, CancellationToken cancellationToken)
        {
            var completion = new FastTaskCompletionSource <T>();

            var disposable = new SingleAssignmentDisposable();
            var ctr        = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() =>
                {
                    completion.TrySetCanceled();
                    disposable.Dispose();
                });
            }

            disposable.Disposable = source.Schedule(
                () =>
            {
                if (disposable.IsDisposed)
                {
                    return;                             // CT canceled
                }

                try
                {
                    var result = func();
                    completion.TrySetResult(result);
                }
                catch (Exception e)
                {
                    completion.TrySetException(e);
                }
                finally
                {
                    ctr.Dispose();
                }
            }
                );

            return(completion.Task);
        }
Exemple #13
0
        private void Start()
        {
            SetUp();

            float time = 0.0f;
            SingleAssignmentDisposable disposable = new SingleAssignmentDisposable();

            disposable.Disposable = Observable.EveryFixedUpdate()
                                    .Subscribe(_ =>
            {
                time += Time.fixedDeltaTime;
                Effect(time);

                if (time >= effectSeconds)
                {
                    TearDown();
                    disposable.Dispose();
                }
            });
        }
Exemple #14
0
        public IDisposable Schedule <TState> (TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action)
#endif
        {
            var  dis    = new SingleAssignmentDisposable();
            bool cancel = false;
            var  th     = thread_factory(() => {
                Thread.Sleep(Scheduler.Normalize(dueTime));
                if (!cancel)
                {
                    dis.Disposable = action(this, state);
                }
            });

            th.Start();
            // The thread is not aborted even if it's at work (ThreadAbortException is not caught inside the action).
            var ret = Disposable.Create(() => { cancel = true; dis.Dispose(); disposables.Remove(dis); });

            disposables.Add(ret);
            return(ret);
        }
Exemple #15
0
        private static void Impl()
        {
            var rand = new Random();

            for (int i = 0; i < 1000; i++)
            {
                var d  = new SingleAssignmentDisposable();
                var e  = new ManualResetEvent(false);
                var cd = new CountdownEvent(2);

                var sleep1 = rand.Next(0, 1) == 0 ? 0 : rand.Next(2, 100);
                var sleep2 = rand.Next(0, 1) == 0 ? 0 : rand.Next(2, 100);

                ThreadPool.QueueUserWorkItem(_ =>
                {
                    Helpers.SleepOrSpin(sleep1);

                    Console.Write("{DB} ");
                    d.Dispose();
                    Console.Write("{DE} ");

                    cd.Signal();
                });

                ThreadPool.QueueUserWorkItem(_ =>
                {
                    Helpers.SleepOrSpin(sleep2);

                    Console.Write("{AB} ");
                    d.Disposable = Disposable.Create(() => e.Set());
                    Console.Write("{AE} ");

                    cd.Signal();
                });

                e.WaitOne();
                cd.Wait();

                Console.WriteLine(".");
            }
        }
        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();
            }
        }
Exemple #17
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);
            }
Exemple #18
0
 public override void OnCompleted()
 {
     isStopped = true;
     if (collectionDisposable.Count == 1)
     {
         lock (gate)
         {
             try
             {
                 observer.OnCompleted();
             }
             finally
             {
                 Dispose();
             }
         }
     }
     else
     {
         sourceDisposable.Dispose();
     }
 }
        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)));
        }
        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();
        }
Exemple #21
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();
            }
        }
Exemple #22
0
        public static void SingleAssignmentDisposable_WillOnlyAllowSettingTheUnderlyingDisposableOnce_FurtherModificationsWillMakeItThrow()
        {
            var singleAssignmentDisposable = new SingleAssignmentDisposable();
            var notDisposedDisposable      = Disposable.Create(() => Console.WriteLine("I am gonna be disposed because I was first."));
            var replacementDisposable      = new BooleanDisposable();//Disposable.Create(() => Console.WriteLine("I can't replace the first assigned disposable. Estupido!"));

            singleAssignmentDisposable.Disposable = notDisposedDisposable;

            try
            {
                singleAssignmentDisposable.Disposable = replacementDisposable;
            }
            catch
            {
                Console.WriteLine("Told you you can't replace it once it has been set.");
            }

            Console.WriteLine("Disposing of the single assignement disposable.");
            singleAssignmentDisposable.Dispose();

            Console.WriteLine($"Single assignement disposable is disposed: {singleAssignmentDisposable.IsDisposed}.");
            Console.WriteLine($"Replacement disposable is disposed: {replacementDisposable.IsDisposed}.");
        }
Exemple #23
0
    public void GameOver()
    {
        if (isCleared)
        {
            return;
        }
        isGameOver = true;
        gameOverImage.SetActive(true);
        clearCountText.text = "";
        var disposable = new SingleAssignmentDisposable();

        disposable.Disposable = this.UpdateAsObservable().Where(_ => isJumped).Subscribe(_ =>
        {
            if (Input.anyKey)
            {
                gameOverImage.SetActive(false);
                Reflesher.Reflesh();
                StartStage();
                isGameOver = false;
                disposable.Dispose();
            }
        });
    }
Exemple #24
0
    static public IStream <T> Join <T>(this ICell <IStream <T> > cell)
    {
        return(new AnonymousStream <T>((Action <T> reaction, Priority p) =>
        {
            SingleAssignmentDisposable mainDisposable = new SingleAssignmentDisposable();
            SingleAssignmentDisposable inner = new SingleAssignmentDisposable();
            CellJoinDisposable <T> group = new CellJoinDisposable <T> {
                mainDisposable, inner
            };

            Action <IStream <T> > func = (IStream <T> innerStream) =>
            {
                inner.Dispose();
                if (innerStream != null)
                {
                    inner.Disposable = innerStream.Listen(reaction, p);
                }
            };

            mainDisposable.Disposable = cell.Bind(func, p);
            return group;
        }));
    }
Exemple #25
0
    public static ICell <T> Join <T>(this ICell <ICell <T> > cell)
    {
        return(new AnonymousCell <T>((Action <T> reaction, Priority p) =>
        {
            SingleAssignmentDisposable mainDisposable = new SingleAssignmentDisposable();
            SingleAssignmentDisposable inner = new SingleAssignmentDisposable();
            CellJoinDisposable <T> group = new CellJoinDisposable <T> {
                mainDisposable, inner
            };
            group.lastValue = cell.value.value;

            Action <ICell <T> > func = (ICell <T> innerCell) =>
            {
                if (!inner.IsDisposed)
                {
                    T value = innerCell.value;
                    if (!object.Equals(group.lastValue, value))
                    {
                        reaction(value);
                        group.lastValue = value;
                    }
                    inner.Dispose();
                }

                inner.Disposable = innerCell.ListenUpdates(val =>
                {
                    reaction(val);
                    group.lastValue = val;
                }, p);
            };

            func(cell.value);

            mainDisposable.Disposable = cell.ListenUpdates(func, p);
            return group;
        }, () => cell.value.value));
    }
        public void SchedulePeriodic()
        {
            var evt = new ManualResetEvent(false);

            var id = Thread.CurrentThread.ManagedThreadId;

            var disp = DispatcherHelpers.EnsureDispatcher();
            var sch  = new DispatcherScheduler(disp);

            var d = new SingleAssignmentDisposable();

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

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

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

                if (n > 3)
                {
                    Assert.Fail();
                }

                return(n + 1);
            });

            evt.WaitOne();
            disp.InvokeShutdown();
        }
Exemple #27
0
        /// <summary>
        /// Awaits a task execution on the specified scheduler, providing the result.
        /// </summary>
        /// <returns>A task that will provide the result of the execution.</returns>
        public static Task <T> Run <T>(this IScheduler source, Func <CancellationToken, Task <T> > taskBuilder, CancellationToken cancellationToken)
        {
            var completion = new FastTaskCompletionSource <T>();

            var disposable = new SingleAssignmentDisposable();
            var ctr        = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() =>
                {
                    completion.TrySetCanceled();
                    disposable.Dispose();
                });
            }

            disposable.Disposable = source.ScheduleTask(
                async(ct, _) =>
            {
                try
                {
                    var result = await taskBuilder(ct);
                    completion.TrySetResult(result);
                }
                catch (Exception e)
                {
                    completion.TrySetException(e);
                }
                finally
                {
                    ctr.Dispose();
                }
            }
                );

            return(completion.Task);
        }
Exemple #28
0
        public void RepeatingTimer_Start_CatchUp()
        {
            var e = new ManualResetEvent(false);

            var xs = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMilliseconds(10));

            var d = new SingleAssignmentDisposable();

            d.Disposable = xs.Subscribe(x =>
            {
                if (x == 0)
                {
                    Thread.Sleep(500);
                }

                if (x > 10)
                {
                    e.Set();
                    d.Dispose();
                }
            });

            e.WaitOne();
        }
Exemple #29
0
 public void Dispose()
 {
     actionSubscription.Dispose();
 }
        private static Task ForEachAsync_ <TSource>(IObservable <TSource> source, Action <TSource> onNext, CancellationToken cancellationToken)
        {
            var tcs          = new TaskCompletionSource <object>();
            var subscription = new SingleAssignmentDisposable();

            var ctr = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() =>
                {
                    tcs.TrySetCanceled(cancellationToken);
                    subscription.Dispose();
                });
            }

            if (!cancellationToken.IsCancellationRequested)
            {
                // Making sure we always complete, even if disposing throws.
                var dispose = new Action <Action>(action =>
                {
                    try
                    {
                        ctr.Dispose(); // no null-check needed (struct)
                        subscription.Dispose();
                    }
                    catch (Exception ex)
                    {
                        tcs.TrySetException(ex);
                        return;
                    }

                    action();
                });

                var taskCompletionObserver = new AnonymousObserver <TSource>(
                    x =>
                {
                    if (!subscription.IsDisposed)
                    {
                        try
                        {
                            onNext(x);
                        }
                        catch (Exception exception)
                        {
                            dispose(() => tcs.TrySetException(exception));
                        }
                    }
                },
                    exception =>
                {
                    dispose(() => tcs.TrySetException(exception));
                },
                    () =>
                {
                    dispose(() => tcs.TrySetResult(null));
                }
                    );

                //
                // Subtle race condition: if the source completes before we reach the line below, the SingleAssigmentDisposable
                // will already have been disposed. Upon assignment, the disposable resource being set will be disposed on the
                // spot, which may throw an exception. (See TFS 487142)
                //
                try
                {
                    //
                    // [OK] Use of unsafe Subscribe: we're catching the exception here to set the TaskCompletionSource.
                    //
                    // Notice we could use a safe subscription to route errors through OnError, but we still need the
                    // exception handling logic here for the reason explained above. We cannot afford to throw here
                    // and as a result never set the TaskCompletionSource, so we tunnel everything through here.
                    //
                    subscription.Disposable = source.Subscribe/*Unsafe*/ (taskCompletionObserver);
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }

            return(tcs.Task);
        }
Exemple #31
0
        private static void RefCountWithPost_(IEnumerable <Tuple <int, int> > parameters)
        {
            var worker = new Thread(() =>
            {
                SynchronizationContext.SetSynchronizationContext(new MySyncCtx());

                foreach (var p in parameters)
                {
                    var N = p.Item1;
                    var M = p.Item2;

                    Console.Write("N = {0}, M = {1} - ", N, M);

                    var bar = new Bar();

                    var foo = Observable.FromEventPattern <FooEventArgs>(h => { /*Console.Write("+");*/ bar.Foo += h; }, h => { bar.Foo -= h; /*Console.Write("-"); */ });

                    var e = new ManualResetEvent(false);

                    var cd = new CountdownEvent(M * 2);
                    for (int i = 0; i < M; i++)
                    {
                        var f = new SingleAssignmentDisposable();

                        ThreadPool.QueueUserWorkItem(_ =>
                        {
                            f.Disposable = foo.Subscribe(__ => { /*Console.Write("!");*/ });
                            cd.Signal();
                        });

                        ThreadPool.QueueUserWorkItem(_ =>
                        {
                            f.Dispose();
                            cd.Signal();
                        });
                    }

                    var hasObserved = 0;

                    Console.Write("{SB}");

                    var d = foo.Subscribe(x =>
                    {
                        //
                        // [on BARTDE-M6500 with CPU and RAM pressure]
                        //
                        // Up to 8K concurrent observers, we typically don't see a time gap (expected worst-case behavior).
                        // The code below uses an event to check the desired behavior of eventually tuning in to the event stream.
                        //
                        Console.Write("&" + x.EventArgs.Qux);
                        e.Set();
                        Interlocked.Exchange(ref hasObserved, 1);
                    });

                    Console.Write("{SE}");

                    var t = new Thread(() =>
                    {
                        Console.Write("{TB}");

                        var i = 0;
                        while (Thread.VolatileRead(ref hasObserved) == 0)
                        {
                            bar.OnFoo(i++);
                        }

                        Console.Write("{TE}");
                    });

                    t.Start();
                    t.Join();

                    cd.Wait();

                    e.WaitOne();
                    d.Dispose();

                    Console.WriteLine(".");
                }
            });

            worker.Start();
            worker.Join();
        }
        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);
            }
        }