public void RunSynchronously(CancellationToken cancellationToken = default) { if (TickHandler == null) { throw new NullReferenceException($"{nameof(TickHandler)} cannot be null reference."); } _simulatedTime = Settings.StartTime; TimeSpan simulatedInterval = TimeSpan.FromMilliseconds(Settings.IntervalMs); long intervalInTicks = Settings.IntervalMs * _tickProvider.TicksPerSecond / 1000; intervalInTicks = (long)(intervalInTicks / Settings.SpeedFactor); long nextTick = _tickProvider.GetTimestamp() + intervalInTicks; while (_simulatedTime <= Settings.StopTime) { if (cancellationToken.IsCancellationRequested) { return; } TickHandler(_simulatedTime); long timestamp; while ((timestamp = _tickProvider.GetTimestamp()) < nextTick) { long tillNextTickInTicks = nextTick - timestamp; if (tillNextTickInTicks <= 0) { break; } _tickProvider.Sleep(tillNextTickInTicks); } nextTick += intervalInTicks; _simulatedTime += simulatedInterval; } }