コード例 #1
0
        public void DispatchAfterRunsFunctionAfterElapsedTime()
        {
            var hit = new List <int>();

            sq.DispatchAfter(TimeSpan.FromMilliseconds(100), () => hit.Add(1));

            Assert.AreEqual(0, hit.Count);
            Assert.AreEqual(0, mockPool.Actions.Count);
            Assert.AreEqual(1, mockPool.ScheduledActions.Count);

            mockPool.AdvanceClock(TimeSpan.FromMilliseconds(99));

            Assert.AreEqual(0, hit.Count);
            Assert.AreEqual(0, mockPool.Actions.Count);
            Assert.AreEqual(1, mockPool.ScheduledActions.Count);

            mockPool.AdvanceClock(TimeSpan.FromMilliseconds(2));

            Assert.AreEqual(0, hit.Count);
            Assert.AreEqual(1, mockPool.Actions.Count);
            Assert.AreEqual(0, mockPool.ScheduledActions.Count);

            mockPool.RunNextAction();

            CollectionAssert.AreEqual(new[] { 1 }, hit);
            Assert.AreEqual(0, mockPool.Actions.Count);
            Assert.AreEqual(0, mockPool.ScheduledActions.Count);
        }
コード例 #2
0
        private bool HandleError(C4Error error)
        {
            // If this is a transient error, or if I'm continuous and the error might go away with a change
            // in network (i.e. network down, hostname unknown), then go offline and retry later
            var transient = Native.c4error_mayBeTransient(error);

            if (!transient && !(Config.Continuous && Native.c4error_mayBeNetworkDependent(error)))
            {
                return(false); // Nope, this is permanent
            }

            if (!Config.Continuous && _retryCount >= MaxOneShotRetryCount)
            {
                return(false); //Too many retries
            }

            ClearRepl();
            if (transient)
            {
                // On transient error, retry periodically, with exponential backoff
                var delay = RetryDelay(++_retryCount);
                Log.To.Sync.I(Tag,
                              $"{this}: Transient error ({Native.c4error_getMessage(error)}); will retry in {delay}...");
                _threadSafetyQueue.DispatchAfter(Retry, delay);
            }
            else
            {
                Log.To.Sync.I(Tag,
                              $"{this}: Network error ({Native.c4error_getMessage(error)}); will retry when network changes...");
            }

            // Also retry when the network changes
            StartReachabilityObserver();
            return(true);
        }
コード例 #3
0
        public void CantCallDispatchAfterOnDisposedQueue()
        {
            var sq = new SerialQueue(invalidPool);

            sq.Dispose();
            var hit = new List <int>();

            AssertEx.Throws <ObjectDisposedException>(() => {
                sq.DispatchAfter(TimeSpan.FromMilliseconds(100), () => hit.Add(1));
            });
        }
コード例 #4
0
        public void TimerQueueFiresInProperOrder()
        {
            SerialQueue    queue      = new SerialQueue(new ManagedThreadPoolDispatcher());
            AutoResetEvent waitHandle = new AutoResetEvent(false);

            int numberOfExecutions = 0;

            bool firstSucceeded  = false;
            bool secondSucceeded = false;
            bool thirdSucceeded  = false;

            WaitCallback first = (_) =>
            {
                firstSucceeded = numberOfExecutions == 0;
                numberOfExecutions++;
            };

            WaitCallback second = (_) =>
            {
                secondSucceeded = numberOfExecutions == 1;
                numberOfExecutions++;
            };

            WaitCallback third = (_) =>
            {
                thirdSucceeded = numberOfExecutions == 2;
                numberOfExecutions++;
                waitHandle.Set();
            };

            queue.DispatchAfter(TimeSpan.FromMilliseconds(15), null, first);
            queue.DispatchAfter(TimeSpan.FromMilliseconds(30), null, second);
            queue.DispatchAfter(TimeSpan.FromMilliseconds(45), null, third);

            Assert.IsTrue(waitHandle.WaitOne(TimeSpan.FromSeconds(1)));

            Assert.IsTrue(firstSucceeded);
            Assert.IsTrue(secondSucceeded);
            Assert.IsTrue(thirdSucceeded);
        }
コード例 #5
0
        public async Task TestSerialQueue()
        {
            var queue  = new SerialQueue();
            var now    = DateTime.Now;
            var then   = now;
            var ignore = queue.DispatchAfter(() => then = DateTime.Now, TimeSpan.FromSeconds(1));
            await Task.Delay(250);

            then.Should().Be(now);
            await Task.Delay(800);

            then.Should().NotBe(now);

            var testBool = false;

            queue.DispatchSync(() => Volatile.Read(ref testBool)).Should().BeFalse();

            var t = queue.DispatchAfter(() => Volatile.Read(ref testBool), TimeSpan.FromMilliseconds(500));

            Volatile.Write(ref testBool, true);
            (await t).Should().BeTrue();
        }
コード例 #6
0
        public void TimerQueueActuallyFires()
        {
            SerialQueue    queue      = new SerialQueue(new ManagedThreadPoolDispatcher());
            AutoResetEvent waitHandle = new AutoResetEvent(false);

            WaitCallback cb = (_) =>
            {
                waitHandle.Set();
            };

            queue.DispatchAfter(TimeSpan.FromMilliseconds(10), null, cb);

            Assert.IsTrue(waitHandle.WaitOne(TimeSpan.FromSeconds(1)));
        }