// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // The refire control. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.Controls { using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Windows; /// /// The refire control. /// public class RefireControl { #region Constants and Fields /// /// How long stages last. /// private const int StageDurationMsec = 900; /// /// The delays. At each stage the refire rate increases. /// private static readonly List Delays = new List { 500, 200, 100, 50, 20 }; /// /// The refire action. /// private readonly Action refireAction; /// /// The refire sync. /// private readonly object refireSync = new object(); /// /// The refire timer. /// private Timer refireTimer; /// /// The running. /// private bool running; /// /// The stopwatch. /// private Stopwatch stopwatch; #endregion #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// The refire action. /// public RefireControl(Action refireAction) { this.refireAction = refireAction; } #endregion #region Public Methods /// /// The begin. /// public void Begin() { lock (this.refireSync) { this.stopwatch = Stopwatch.StartNew(); this.running = true; // Fire once immediately. this.refireAction(); this.refireTimer = new Timer( obj => { lock (this.refireSync) { if (this.running) { var stage = (int)(this.stopwatch.ElapsedMilliseconds / StageDurationMsec); int newDelay = stage >= Delays.Count ? Delays[Delays.Count - 1] : Delays[stage]; Application.Current.Dispatcher.BeginInvoke(this.refireAction); this.refireTimer.Change(newDelay, newDelay); } } }, null, Delays[0], Delays[0]); } } /// /// The stop. /// public void Stop() { lock (this.refireSync) { this.stopwatch.Stop(); this.running = false; if (this.refireTimer != null) { this.refireTimer.Dispose(); } } } #endregion } }