protected virtual async Task StopAeration(bool showFinish = false) { lock (aerateLock) { if (!aerating || stopping) { return; } stopping = true; } CrossKeepAwakeService.Instance.StopAwake(); // Stop keep awake. if (aerateCancelledSource != null) { aerateCancelledSource.Cancel(); } CrossVibrate.Current.StopVibration(); if (fluidSim != null) { fluidSim.UnlockMotion(); } int fadeTimeMillis = 400; // Show finish message if we completed full process. if (showFinish) { int totalMessageTime = EstimatedReadTimeMillis(BeverageResources.AerateFinishMessage) + (fadeTimeMillis * 2); var tES = EnableStartButton((totalMessageTime + fadeTimeMillis + 200) / 2); var tSF = ShowFinishMessage(fadeTimeMillis); var tSDS = Task.Run(async() => { await Task.Delay(totalMessageTime); await EnableDurationSlider(fadeTimeMillis); }); AnimateOnMain(async() => { await Task.Delay(totalMessageTime); await glassHereContainer.FadeTo(100, (uint)fadeTimeMillis); }); await Task.WhenAll(tES, tSF, tSDS); } else { var tES = EnableStartButton(fadeTimeMillis / 2); var tED = EnableDurationSlider(fadeTimeMillis); AnimateOnMain(async() => await glassHereContainer.FadeTo(100, (uint)fadeTimeMillis)); await Task.WhenAll(tES, tED); } await StartShake(); // Restart shake. lock (aerateLock) { aerating = false; // Stop flag. stopping = false; } // Show ad unless we quickly cancelled (< 5 seconds run time). if (aerateTimer.ElapsedMilliseconds >= 5000) { CrossInterstitialAdService.Instance.ShowAd(); } }