PeriodicTimerSystemClockMonitor
(Infrastructure) Monitors for system clock changes based on a periodic timer.
            
                using System.ComponentModel;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace System.Reactive.PlatformServices
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public class PeriodicTimerSystemClockMonitor : INotifySystemClockChanged
    {
        private readonly TimeSpan _period;
        private SerialDisposableValue _timer;
        private long _lastTimeUnixMillis;
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            2,
            1
        })]
        private EventHandler<SystemClockChangedEventArgs> _systemClockChanged;
        private const int SyncMaxRetries = 100;
        private const double SyncMaxDelta = 10;
        private const int MaxError = 100;
        public event EventHandler<SystemClockChangedEventArgs> SystemClockChanged {
            add {
                NewTimer();
                _systemClockChanged = (EventHandler<SystemClockChangedEventArgs>)Delegate.Combine(_systemClockChanged, value);
            }
            remove {
                _systemClockChanged = (EventHandler<SystemClockChangedEventArgs>)Delegate.Remove(_systemClockChanged, value);
                _timer.Disposable = Disposable.Empty;
            }
        }
        public PeriodicTimerSystemClockMonitor(TimeSpan period)
        {
            _period = period;
        }
        private void NewTimer()
        {
            _timer.Disposable = Disposable.Empty;
            long num = 0;
            while (true) {
                DateTimeOffset utcNow = SystemClock.UtcNow;
                long num2 = utcNow.ToUnixTimeMilliseconds();
                Interlocked.Exchange(ref _lastTimeUnixMillis, num2);
                _timer.Disposable = ConcurrencyAbstractionLayer.Current.StartPeriodicTimer(TimeChanged, _period);
                utcNow = SystemClock.UtcNow;
                if ((double)Math.Abs(utcNow.ToUnixTimeMilliseconds() - num2) <= 10 || _timer.Disposable == Disposable.Empty)
                    break;
                if (++num >= 100)
                    Task.Delay(10).Wait();
            }
        }
        private void TimeChanged()
        {
            DateTimeOffset utcNow = SystemClock.UtcNow;
            long num = utcNow.ToUnixTimeMilliseconds();
            long num2 = (long)((double)Volatile.Read(ref _lastTimeUnixMillis) + _period.TotalMilliseconds);
            if (Math.Abs(num - num2) >= 100) {
                _systemClockChanged?.Invoke(this, new SystemClockChangedEventArgs(DateTimeOffset.FromUnixTimeMilliseconds(num2), utcNow));
                NewTimer();
            } else
                Interlocked.Exchange(ref _lastTimeUnixMillis, SystemClock.UtcNow.ToUnixTimeMilliseconds());
        }
    }
}