private void UpdaterTask() { _updaterRunning = true; _autoUpdate = false; var targetTpf = 1000 / TargetFps; var lastMusicTime = 0; var lastComputedTime = 0; var lastStartTime = DateTime.UtcNow; while (_updaterRunning) { var startTime = DateTime.UtcNow; var musicTime = (int)_musicWave.CurrentTime.TotalMilliseconds; if (musicTime == lastMusicTime) { musicTime = lastComputedTime + (int)(lastStartTime - startTime).TotalMilliseconds; } else { lastMusicTime = musicTime; } if (musicTime > lastComputedTime) { lastComputedTime = musicTime; } lastStartTime = startTime; EditorStatus.Current.CurrentTime = musicTime; SetCurrentBeatFromTime(); RulerCanvas.Render(); EditorCanvas.ComputeAndRender(); var endTime = DateTime.UtcNow; var elapsedMs = (endTime - startTime).TotalMilliseconds; if (elapsedMs < targetTpf) { Thread.Sleep((int)(targetTpf - elapsedMs)); } } _autoUpdate = true; }