Browse Source

Refactored dispatcher clock

Nikita Tsukanov 2 years ago
parent
commit
dbbdcb95cd

+ 6 - 5
src/Avalonia.Base/Threading/Dispatcher.Queue.cs

@@ -23,7 +23,7 @@ public partial class Dispatcher
             }
             }
             else if (_dueTimeForBackgroundProcessing == null)
             else if (_dueTimeForBackgroundProcessing == null)
             {
             {
-                _dueTimeForBackgroundProcessing = Clock.TickCount + 1;
+                _dueTimeForBackgroundProcessing = Now + 1;
                 UpdateOSTimer();
                 UpdateOSTimer();
             }
             }
         }
         }
@@ -68,7 +68,8 @@ public partial class Dispatcher
 
 
         public event Action? Signaled;
         public event Action? Signaled;
         public event Action? Timer;
         public event Action? Timer;
-        public void UpdateTimer(int? dueTimeInMs)
+        public long Now => 0;
+        public void UpdateTimer(long? dueTimeInMs)
         {
         {
         }
         }
     }
     }
@@ -119,7 +120,7 @@ public partial class Dispatcher
 
 
     void ExecuteJobsCore()
     void ExecuteJobsCore()
     {
     {
-        int? backgroundJobExecutionStartedAt = null;
+        long? backgroundJobExecutionStartedAt = null;
         while (true)
         while (true)
         {
         {
             DispatcherOperation? job;
             DispatcherOperation? job;
@@ -153,9 +154,9 @@ public partial class Dispatcher
             else
             else
             {
             {
                 if (backgroundJobExecutionStartedAt == null)
                 if (backgroundJobExecutionStartedAt == null)
-                    backgroundJobExecutionStartedAt = Clock.TickCount;
+                    backgroundJobExecutionStartedAt = Now;
                 
                 
-                if (Clock.TickCount - backgroundJobExecutionStartedAt.Value > MaximumTimeProcessingBackgroundJobs)
+                if (Now - backgroundJobExecutionStartedAt.Value > MaximumTimeProcessingBackgroundJobs)
                 {
                 {
                     _signaled = true;
                     _signaled = true;
                     RequestBackgroundProcessing();
                     RequestBackgroundProcessing();

+ 10 - 8
src/Avalonia.Base/Threading/Dispatcher.Timers.cs

@@ -9,11 +9,13 @@ public partial class Dispatcher
     private List<DispatcherTimer> _timers = new();
     private List<DispatcherTimer> _timers = new();
     private long _timersVersion;
     private long _timersVersion;
     private bool _dueTimeFound;
     private bool _dueTimeFound;
-    private int _dueTimeInMs;
+    private long _dueTimeInMs;
 
 
-    private int? _dueTimeForTimers;
-    private int? _dueTimeForBackgroundProcessing;
-    private int? _osTimerSetTo;
+    private long? _dueTimeForTimers;
+    private long? _dueTimeForBackgroundProcessing;
+    private long? _osTimerSetTo;
+
+    internal long Now => _impl.Now;
 
 
     private void UpdateOSTimer()
     private void UpdateOSTimer()
     {
     {
@@ -40,7 +42,7 @@ public partial class Dispatcher
             if (!_hasShutdownFinished) // Dispatcher thread, does not technically need the lock to read
             if (!_hasShutdownFinished) // Dispatcher thread, does not technically need the lock to read
             {
             {
                 bool oldDueTimeFound = _dueTimeFound;
                 bool oldDueTimeFound = _dueTimeFound;
-                int oldDueTimeInTicks = _dueTimeInMs;
+                long oldDueTimeInTicks = _dueTimeInMs;
                 _dueTimeFound = false;
                 _dueTimeFound = false;
                 _dueTimeInMs = 0;
                 _dueTimeInMs = 0;
 
 
@@ -113,11 +115,11 @@ public partial class Dispatcher
         lock (InstanceLock)
         lock (InstanceLock)
         {
         {
             _impl.UpdateTimer(_osTimerSetTo = null);
             _impl.UpdateTimer(_osTimerSetTo = null);
-            needToPromoteTimers = _dueTimeForTimers.HasValue && _dueTimeForTimers.Value <= Clock.TickCount;
+            needToPromoteTimers = _dueTimeForTimers.HasValue && _dueTimeForTimers.Value <= Now;
             if (needToPromoteTimers)
             if (needToPromoteTimers)
                 _dueTimeForTimers = null;
                 _dueTimeForTimers = null;
             needToProcessQueue = _dueTimeForBackgroundProcessing.HasValue &&
             needToProcessQueue = _dueTimeForBackgroundProcessing.HasValue &&
-                                 _dueTimeForBackgroundProcessing.Value <= Clock.TickCount;
+                                 _dueTimeForBackgroundProcessing.Value <= Now;
             if (needToProcessQueue)
             if (needToProcessQueue)
                 _dueTimeForBackgroundProcessing = null;
                 _dueTimeForBackgroundProcessing = null;
         }
         }
@@ -131,7 +133,7 @@ public partial class Dispatcher
     
     
     internal void PromoteTimers()
     internal void PromoteTimers()
     {
     {
-        int currentTimeInTicks = Clock.TickCount;
+        long currentTimeInTicks = Now;
         try
         try
         {
         {
             List<DispatcherTimer>? timers = null;
             List<DispatcherTimer>? timers = null;

+ 2 - 4
src/Avalonia.Base/Threading/Dispatcher.cs

@@ -17,7 +17,6 @@ namespace Avalonia.Threading;
 public partial class Dispatcher : IDispatcher
 public partial class Dispatcher : IDispatcher
 {
 {
     private IDispatcherImpl _impl;
     private IDispatcherImpl _impl;
-    internal IDispatcherClock Clock { get; }
     internal object InstanceLock { get; } = new();
     internal object InstanceLock { get; } = new();
     private bool _hasShutdownFinished;
     private bool _hasShutdownFinished;
     private IControlledDispatcherImpl? _controlledImpl;
     private IControlledDispatcherImpl? _controlledImpl;
@@ -25,10 +24,9 @@ public partial class Dispatcher : IDispatcher
     private IDispatcherImplWithPendingInput? _pendingInputImpl;
     private IDispatcherImplWithPendingInput? _pendingInputImpl;
     private IDispatcherImplWithExplicitBackgroundProcessing? _backgroundProcessingImpl;
     private IDispatcherImplWithExplicitBackgroundProcessing? _backgroundProcessingImpl;
 
 
-    internal Dispatcher(IDispatcherImpl impl, IDispatcherClock clock)
+    internal Dispatcher(IDispatcherImpl impl)
     {
     {
         _impl = impl;
         _impl = impl;
-        Clock = clock;
         impl.Timer += OnOSTimer;
         impl.Timer += OnOSTimer;
         impl.Signaled += Signaled;
         impl.Signaled += Signaled;
         _controlledImpl = _impl as IControlledDispatcherImpl;
         _controlledImpl = _impl as IControlledDispatcherImpl;
@@ -51,7 +49,7 @@ public partial class Dispatcher : IDispatcher
             else
             else
                 impl = new NullDispatcherImpl();
                 impl = new NullDispatcherImpl();
         }
         }
-        return new Dispatcher(impl, impl as IDispatcherClock ?? new DefaultDispatcherClock());
+        return new Dispatcher(impl);
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 3 - 3
src/Avalonia.Base/Threading/DispatcherTimer.cs

@@ -125,7 +125,7 @@ public partial class DispatcherTimer
 
 
                 if (_isEnabled)
                 if (_isEnabled)
                 {
                 {
-                    DueTimeInMs = _dispatcher.Clock.TickCount + (int)_interval.TotalMilliseconds;
+                    DueTimeInMs = _dispatcher.Now + (long)_interval.TotalMilliseconds;
                     updateOSTimer = true;
                     updateOSTimer = true;
                 }
                 }
             }
             }
@@ -288,7 +288,7 @@ public partial class DispatcherTimer
             // BeginInvoke a new operation.
             // BeginInvoke a new operation.
             _operation = _dispatcher.InvokeAsync(FireTick, DispatcherPriority.Inactive);
             _operation = _dispatcher.InvokeAsync(FireTick, DispatcherPriority.Inactive);
 
 
-            DueTimeInMs = _dispatcher.Clock.TickCount + (int)_interval.TotalMilliseconds;
+            DueTimeInMs = _dispatcher.Now + (long)_interval.TotalMilliseconds;
 
 
             if (_interval.TotalMilliseconds == 0 && _dispatcher.CheckAccess())
             if (_interval.TotalMilliseconds == 0 && _dispatcher.CheckAccess())
             {
             {
@@ -348,5 +348,5 @@ public partial class DispatcherTimer
     private bool _isEnabled;
     private bool _isEnabled;
 
 
     // used by Dispatcher
     // used by Dispatcher
-    internal int DueTimeInMs { get; private set; }
+    internal long DueTimeInMs { get; private set; }
 }
 }

+ 0 - 13
src/Avalonia.Base/Threading/IDispatcherClock.cs

@@ -1,13 +0,0 @@
-using System;
-
-namespace Avalonia.Threading;
-
-internal interface IDispatcherClock
-{
-    int TickCount { get; }
-}
-
-internal class DefaultDispatcherClock : IDispatcherClock
-{
-    public int TickCount => Environment.TickCount;
-}

+ 11 - 5
src/Avalonia.Base/Threading/IDispatcherImpl.cs

@@ -1,4 +1,5 @@
 using System;
 using System;
+using System.Diagnostics;
 using System.Threading;
 using System.Threading;
 using Avalonia.Metadata;
 using Avalonia.Metadata;
 using Avalonia.Platform;
 using Avalonia.Platform;
@@ -14,7 +15,8 @@ public interface IDispatcherImpl
     void Signal();
     void Signal();
     event Action Signaled;
     event Action Signaled;
     event Action Timer;
     event Action Timer;
-    void UpdateTimer(int? dueTimeInMs);
+    long Now { get; }
+    void UpdateTimer(long? dueTimeInMs);
 }
 }
 
 
 [Unstable]
 [Unstable]
@@ -40,10 +42,11 @@ public interface IControlledDispatcherImpl : IDispatcherImplWithPendingInput
     void RunLoop(CancellationToken token);
     void RunLoop(CancellationToken token);
 }
 }
 
 
-internal class LegacyDispatcherImpl : DefaultDispatcherClock, IControlledDispatcherImpl
+internal class LegacyDispatcherImpl : IControlledDispatcherImpl
 {
 {
     private readonly IPlatformThreadingInterface _platformThreading;
     private readonly IPlatformThreadingInterface _platformThreading;
     private IDisposable? _timer;
     private IDisposable? _timer;
+    private Stopwatch _clock = Stopwatch.StartNew();
 
 
     public LegacyDispatcherImpl(IPlatformThreadingInterface platformThreading)
     public LegacyDispatcherImpl(IPlatformThreadingInterface platformThreading)
     {
     {
@@ -56,14 +59,15 @@ internal class LegacyDispatcherImpl : DefaultDispatcherClock, IControlledDispatc
 
 
     public event Action? Signaled;
     public event Action? Signaled;
     public event Action? Timer;
     public event Action? Timer;
-    public void UpdateTimer(int? dueTimeInMs)
+    public long Now => _clock.ElapsedMilliseconds;
+    public void UpdateTimer(long? dueTimeInMs)
     {
     {
         _timer?.Dispose();
         _timer?.Dispose();
         _timer = null;
         _timer = null;
 
 
         if (dueTimeInMs.HasValue)
         if (dueTimeInMs.HasValue)
         {
         {
-            var interval = Math.Max(1, dueTimeInMs.Value - TickCount);
+            var interval = Math.Max(1, dueTimeInMs.Value - _clock.ElapsedMilliseconds);
             _timer = _platformThreading.StartTimer(DispatcherPriority.Send,
             _timer = _platformThreading.StartTimer(DispatcherPriority.Send,
                 TimeSpan.FromMilliseconds(interval),
                 TimeSpan.FromMilliseconds(interval),
                 OnTick);
                 OnTick);
@@ -94,7 +98,9 @@ class NullDispatcherImpl : IDispatcherImpl
     public event Action? Signaled;
     public event Action? Signaled;
     public event Action? Timer;
     public event Action? Timer;
 
 
-    public void UpdateTimer(int? dueTimeInMs)
+    public long Now => 0;
+
+    public void UpdateTimer(long? dueTimeInMs)
     {
     {
         
         
     }
     }

+ 2 - 1
src/Avalonia.Controls/Platform/ManagedDispatcherImpl.cs

@@ -40,7 +40,8 @@ public class ManagedDispatcherImpl : IControlledDispatcherImpl
 
 
     public event Action? Signaled;
     public event Action? Signaled;
     public event Action? Timer;
     public event Action? Timer;
-    public void UpdateTimer(int? dueTimeInMs)
+    public long Now => _clock.ElapsedMilliseconds;
+    public void UpdateTimer(long? dueTimeInMs)
     {
     {
         lock (_lock)
         lock (_lock)
         {
         {

+ 5 - 4
src/Avalonia.Native/DispatcherImpl.cs

@@ -10,10 +10,11 @@ using MicroCom.Runtime;
 
 
 namespace Avalonia.Native;
 namespace Avalonia.Native;
 
 
-internal class DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock, IDispatcherImplWithExplicitBackgroundProcessing
+internal class DispatcherImpl : IControlledDispatcherImpl, IDispatcherImplWithExplicitBackgroundProcessing
 {
 {
     private readonly IAvnPlatformThreadingInterface _native;
     private readonly IAvnPlatformThreadingInterface _native;
     private Thread? _loopThread;
     private Thread? _loopThread;
+    private Stopwatch _clock = Stopwatch.StartNew();
     private Stack<RunLoopFrame> _managedFrames = new();
     private Stack<RunLoopFrame> _managedFrames = new();
 
 
     public DispatcherImpl(IAvnPlatformThreadingInterface native)
     public DispatcherImpl(IAvnPlatformThreadingInterface native)
@@ -57,9 +58,9 @@ internal class DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock, IDi
 
 
     public void Signal() => _native.Signal();
     public void Signal() => _native.Signal();
 
 
-    public void UpdateTimer(int? dueTimeInMs)
+    public void UpdateTimer(long? dueTimeInMs)
     {
     {
-        var ms = dueTimeInMs == null ? -1 : Math.Max(1, dueTimeInMs.Value - TickCount);
+        var ms = dueTimeInMs == null ? -1 : (int)Math.Min(int.MaxValue - 10, Math.Max(1, dueTimeInMs.Value - Now));
         _native.UpdateTimer(ms);
         _native.UpdateTimer(ms);
     }
     }
 
 
@@ -113,7 +114,7 @@ internal class DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock, IDi
         }
         }
     }
     }
 
 
-    public int TickCount => Environment.TickCount;
+    public long Now => _clock.ElapsedMilliseconds;
 
 
     public void PropagateCallbackException(ExceptionDispatchInfo capture)
     public void PropagateCallbackException(ExceptionDispatchInfo capture)
     {
     {

+ 3 - 3
src/Avalonia.X11/X11PlatformThreading.cs

@@ -9,7 +9,7 @@ using static Avalonia.X11.XLib;
 
 
 namespace Avalonia.X11
 namespace Avalonia.X11
 {
 {
-    internal unsafe class X11PlatformThreading : IControlledDispatcherImpl, IDispatcherClock
+    internal unsafe class X11PlatformThreading : IControlledDispatcherImpl
     {
     {
         private readonly AvaloniaX11Platform _platform;
         private readonly AvaloniaX11Platform _platform;
         private readonly IntPtr _display;
         private readonly IntPtr _display;
@@ -227,7 +227,7 @@ namespace Avalonia.X11
         public event Action Signaled;
         public event Action Signaled;
         public event Action Timer;
         public event Action Timer;
 
 
-        public void UpdateTimer(int? dueTimeInMs)
+        public void UpdateTimer(long? dueTimeInMs)
         {
         {
             _nextTimer = dueTimeInMs;
             _nextTimer = dueTimeInMs;
             if (_nextTimer != null)
             if (_nextTimer != null)
@@ -235,7 +235,7 @@ namespace Avalonia.X11
         }
         }
 
 
 
 
-        public int TickCount => (int)_clock.ElapsedMilliseconds;
+        public long Now => (int)_clock.ElapsedMilliseconds;
         public bool CanQueryPendingInput => true;
         public bool CanQueryPendingInput => true;
 
 
         public bool HasPendingInput => _platform.EventGrouperDispatchQueue.HasJobs || XPending(_display) != 0;
         public bool HasPendingInput => _platform.EventGrouperDispatchQueue.HasJobs || XPending(_display) != 0;

+ 6 - 4
src/Windows/Avalonia.Win32/Win32DispatcherImpl.cs

@@ -1,4 +1,5 @@
 using System;
 using System;
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading;
 using Avalonia.Threading;
 using Avalonia.Threading;
@@ -6,10 +7,11 @@ using Avalonia.Win32.Interop;
 using static Avalonia.Win32.Interop.UnmanagedMethods;
 using static Avalonia.Win32.Interop.UnmanagedMethods;
 namespace Avalonia.Win32;
 namespace Avalonia.Win32;
 
 
-internal class Win32DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock
+internal class Win32DispatcherImpl : IControlledDispatcherImpl
 {
 {
     private readonly IntPtr _messageWindow;
     private readonly IntPtr _messageWindow;
     private static Thread? s_uiThread;
     private static Thread? s_uiThread;
+    private readonly Stopwatch _clock = Stopwatch.StartNew();
     public Win32DispatcherImpl(IntPtr messageWindow)
     public Win32DispatcherImpl(IntPtr messageWindow)
     {
     {
         _messageWindow = messageWindow;
         _messageWindow = messageWindow;
@@ -36,7 +38,7 @@ internal class Win32DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock
 
 
     public void FireTimer() => Timer?.Invoke();
     public void FireTimer() => Timer?.Invoke();
 
 
-    public void UpdateTimer(int? dueTimeInMs)
+    public void UpdateTimer(long? dueTimeInMs)
     {
     {
         if (dueTimeInMs == null)
         if (dueTimeInMs == null)
         {
         {
@@ -44,7 +46,7 @@ internal class Win32DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock
         }
         }
         else
         else
         {
         {
-            var interval = (uint)Math.Max(1, TickCount - dueTimeInMs.Value);
+            var interval = (uint)Math.Min(int.MaxValue - 10, Math.Max(1, Now - dueTimeInMs.Value));
             SetTimer(
             SetTimer(
                 _messageWindow,
                 _messageWindow,
                 (IntPtr)Win32Platform.TIMERID_DISPATCHER,
                 (IntPtr)Win32Platform.TIMERID_DISPATCHER,
@@ -115,5 +117,5 @@ internal class Win32DispatcherImpl : IControlledDispatcherImpl, IDispatcherClock
         }
         }
     }
     }
 
 
-    public int TickCount => Environment.TickCount;
+    public long Now => _clock.ElapsedMilliseconds;
 }
 }

+ 13 - 13
tests/Avalonia.Base.UnitTests/DispatcherTests.cs

@@ -7,7 +7,7 @@ namespace Avalonia.Base.UnitTests;
 
 
 public class DispatcherTests
 public class DispatcherTests
 {
 {
-    class SimpleDispatcherImpl : IDispatcherImpl, IDispatcherClock, IDispatcherImplWithPendingInput
+    class SimpleDispatcherImpl : IDispatcherImpl, IDispatcherImplWithPendingInput
     {
     {
         public bool CurrentThreadIsLoopThread => true;
         public bool CurrentThreadIsLoopThread => true;
 
 
@@ -15,15 +15,15 @@ public class DispatcherTests
 
 
         public event Action Signaled;
         public event Action Signaled;
         public event Action Timer;
         public event Action Timer;
-        public int? NextTimer { get; private set; }
+        public long? NextTimer { get; private set; }
         public bool AskedForSignal { get; private set; }
         public bool AskedForSignal { get; private set; }
         
         
-        public void UpdateTimer(int? dueTimeInTicks)
+        public void UpdateTimer(long? dueTimeInTicks)
         {
         {
             NextTimer = dueTimeInTicks;
             NextTimer = dueTimeInTicks;
         }
         }
 
 
-        public int TickCount { get; set; }
+        public long Now { get; set; }
 
 
         public void ExecuteSignal()
         public void ExecuteSignal()
         {
         {
@@ -37,7 +37,7 @@ public class DispatcherTests
         {
         {
             if (NextTimer == null)
             if (NextTimer == null)
                 return;
                 return;
-            TickCount = NextTimer.Value;
+            Now = NextTimer.Value;
             Timer?.Invoke();
             Timer?.Invoke();
         }
         }
 
 
@@ -51,7 +51,7 @@ public class DispatcherTests
     public void DispatcherExecutesJobsAccordingToPriority()
     public void DispatcherExecutesJobsAccordingToPriority()
     {
     {
         var impl = new SimpleDispatcherImpl();
         var impl = new SimpleDispatcherImpl();
-        var disp = new Dispatcher(impl, impl);
+        var disp = new Dispatcher(impl);
         var actions = new List<string>();
         var actions = new List<string>();
         disp.Post(()=>actions.Add("Background"), DispatcherPriority.Background);
         disp.Post(()=>actions.Add("Background"), DispatcherPriority.Background);
         disp.Post(()=>actions.Add("Render"), DispatcherPriority.Render);
         disp.Post(()=>actions.Add("Render"), DispatcherPriority.Render);
@@ -65,7 +65,7 @@ public class DispatcherTests
     public void DispatcherPreservesOrderWhenChangingPriority()
     public void DispatcherPreservesOrderWhenChangingPriority()
     {
     {
         var impl = new SimpleDispatcherImpl();
         var impl = new SimpleDispatcherImpl();
-        var disp = new Dispatcher(impl, impl);
+        var disp = new Dispatcher(impl);
         var actions = new List<string>();
         var actions = new List<string>();
         var toPromote = disp.InvokeAsync(()=>actions.Add("PromotedRender"), DispatcherPriority.Background);
         var toPromote = disp.InvokeAsync(()=>actions.Add("PromotedRender"), DispatcherPriority.Background);
         var toPromote2 = disp.InvokeAsync(()=>actions.Add("PromotedRender2"), DispatcherPriority.Input);
         var toPromote2 = disp.InvokeAsync(()=>actions.Add("PromotedRender2"), DispatcherPriority.Input);
@@ -84,7 +84,7 @@ public class DispatcherTests
     public void DispatcherStopsItemProcessingWhenInteractivityDeadlineIsReached()
     public void DispatcherStopsItemProcessingWhenInteractivityDeadlineIsReached()
     {
     {
         var impl = new SimpleDispatcherImpl();
         var impl = new SimpleDispatcherImpl();
-        var disp = new Dispatcher(impl, impl);
+        var disp = new Dispatcher(impl);
         var actions = new List<int>();
         var actions = new List<int>();
         for (var c = 0; c < 10; c++)
         for (var c = 0; c < 10; c++)
         {
         {
@@ -92,7 +92,7 @@ public class DispatcherTests
             disp.Post(() =>
             disp.Post(() =>
             {
             {
                 actions.Add(itemId);
                 actions.Add(itemId);
-                impl.TickCount += 20;
+                impl.Now += 20;
             }, DispatcherPriority.Background);
             }, DispatcherPriority.Background);
         }
         }
 
 
@@ -114,7 +114,7 @@ public class DispatcherTests
             Assert.False(impl.AskedForSignal);
             Assert.False(impl.AskedForSignal);
             if (c < 3)
             if (c < 3)
             {
             {
-                Assert.True(impl.NextTimer > impl.TickCount);
+                Assert.True(impl.NextTimer > impl.Now);
             }
             }
             else
             else
                 Assert.Null(impl.NextTimer);
                 Assert.Null(impl.NextTimer);
@@ -127,7 +127,7 @@ public class DispatcherTests
     {
     {
         var impl = new SimpleDispatcherImpl();
         var impl = new SimpleDispatcherImpl();
         impl.TestInputPending = true;
         impl.TestInputPending = true;
-        var disp = new Dispatcher(impl, impl);
+        var disp = new Dispatcher(impl);
         var actions = new List<int>();
         var actions = new List<int>();
         for (var c = 0; c < 10; c++)
         for (var c = 0; c < 10; c++)
         {
         {
@@ -160,8 +160,8 @@ public class DispatcherTests
             Assert.False(impl.AskedForSignal);
             Assert.False(impl.AskedForSignal);
             if (c < 3)
             if (c < 3)
             {
             {
-                Assert.True(impl.NextTimer > impl.TickCount);
-                impl.TickCount = impl.NextTimer.Value + 1;
+                Assert.True(impl.NextTimer > impl.Now);
+                impl.Now = impl.NextTimer.Value + 1;
             }
             }
             else
             else
                 Assert.Null(impl.NextTimer);
                 Assert.Null(impl.NextTimer);