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); }
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); }
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)); }); }
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); }
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(); }
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))); }