|
|
|
@ -11,6 +11,9 @@ namespace Perspex.Threading |
|
|
|
using Perspex.Platform; |
|
|
|
using Splat; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// A timer that uses a <see cref="Dispatcher"/> to fire at a specified interval.
|
|
|
|
/// </summary>
|
|
|
|
public class DispatcherTimer |
|
|
|
{ |
|
|
|
private IDisposable timer; |
|
|
|
@ -19,24 +22,43 @@ namespace Perspex.Threading |
|
|
|
|
|
|
|
private TimeSpan interval; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
|
|
|
|
/// </summary>
|
|
|
|
public DispatcherTimer() |
|
|
|
{ |
|
|
|
this.priority = DispatcherPriority.Normal; |
|
|
|
this.Dispatcher = Dispatcher.UIThread; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="priority">The priority to use.</param>
|
|
|
|
public DispatcherTimer(DispatcherPriority priority) |
|
|
|
{ |
|
|
|
this.priority = priority; |
|
|
|
this.Dispatcher = Dispatcher.UIThread; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="priority">The priority to use.</param>
|
|
|
|
/// <param name="dispatcher">The dispatcher to use.</param>
|
|
|
|
public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher) |
|
|
|
{ |
|
|
|
this.priority = priority; |
|
|
|
this.Dispatcher = dispatcher; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="interval">The interval at which to tick.</param>
|
|
|
|
/// <param name="priority">The priority to use.</param>
|
|
|
|
/// <param name="dispatcher">The dispatcher to use.</param>
|
|
|
|
/// <param name="callback">The event to call when the timer ticks.</param>
|
|
|
|
public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher) |
|
|
|
{ |
|
|
|
this.priority = priority; |
|
|
|
@ -45,6 +67,9 @@ namespace Perspex.Threading |
|
|
|
this.Tick += callback; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Finalizes an instance of the <see cref="DispatcherTimer"/> class.
|
|
|
|
/// </summary>
|
|
|
|
~DispatcherTimer() |
|
|
|
{ |
|
|
|
if (this.timer != null) |
|
|
|
@ -53,14 +78,23 @@ namespace Perspex.Threading |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raised when the timer ticks.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler Tick; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the dispatcher that the timer uses.
|
|
|
|
/// </summary>
|
|
|
|
public Dispatcher Dispatcher |
|
|
|
{ |
|
|
|
get; |
|
|
|
private set; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the interval at which the timer ticks.
|
|
|
|
/// </summary>
|
|
|
|
public TimeSpan Interval |
|
|
|
{ |
|
|
|
get |
|
|
|
@ -77,6 +111,9 @@ namespace Perspex.Threading |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a value indicating whether the timer is running.
|
|
|
|
/// </summary>
|
|
|
|
public bool IsEnabled |
|
|
|
{ |
|
|
|
get |
|
|
|
@ -100,12 +137,24 @@ namespace Perspex.Threading |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets user-defined data associated with the timer.
|
|
|
|
/// </summary>
|
|
|
|
public object Tag |
|
|
|
{ |
|
|
|
get; |
|
|
|
set; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Starts a new timer.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="action">
|
|
|
|
/// The method to call on timer tick. If the method returns false, the timer will stop.
|
|
|
|
/// </param>
|
|
|
|
/// <param name="interval">The interval at which to tick.</param>
|
|
|
|
/// <param name="priority">The priority to use.</param>
|
|
|
|
/// <returns>An <see cref="IDisposable"/> used to cancel the timer.</returns>
|
|
|
|
public static IDisposable Run(Func<bool> action, TimeSpan interval, DispatcherPriority priority = DispatcherPriority.Normal) |
|
|
|
{ |
|
|
|
var timer = new DispatcherTimer(priority); |
|
|
|
@ -124,6 +173,9 @@ namespace Perspex.Threading |
|
|
|
return Disposable.Create(() => timer.Stop()); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Starts the timer.
|
|
|
|
/// </summary>
|
|
|
|
public void Start() |
|
|
|
{ |
|
|
|
if (!this.IsEnabled) |
|
|
|
@ -133,6 +185,9 @@ namespace Perspex.Threading |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Stops the timer.
|
|
|
|
/// </summary>
|
|
|
|
public void Stop() |
|
|
|
{ |
|
|
|
if (this.IsEnabled) |
|
|
|
@ -143,11 +198,17 @@ namespace Perspex.Threading |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raises the <see cref="Tick"/> event on the dispatcher thread.
|
|
|
|
/// </summary>
|
|
|
|
private void InternalTick() |
|
|
|
{ |
|
|
|
this.Dispatcher.InvokeAsync(this.RaiseTick, this.priority); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raises the <see cref="Tick"/> event.
|
|
|
|
/// </summary>
|
|
|
|
private void RaiseTick() |
|
|
|
{ |
|
|
|
if (this.Tick != null) |
|
|
|
|