@ -7,65 +7,102 @@ namespace Avalonia.Threading;
/// A timer that is integrated into the Dispatcher queues, and will
/// A timer that is integrated into the Dispatcher queues, and will
/// be processed after a given amount of time at a specified priority.
/// be processed after a given amount of time at a specified priority.
/// </summary>
/// </summary>
public partial class DispatcherTimer
public class DispatcherTimer
{
{
internal static int ActiveTimersCount { get ; private set ; }
internal static int ActiveTimersCount { get ; private set ; }
/// <summary>
/// <summary>
/// Creates a timer that uses theUI thread's Dispatcher2 to
/// Creates a timer that uses <see cref="Avalonia.Threading.Dispatcher.CurrentDispatcher"/> to
/// process the timer event at background priority.
/// process the timer event at background priority.
/// </summary>
/// </summary>
public DispatcherTimer ( ) : this ( DispatcherPriority . Background )
public DispatcherTimer ( )
: this ( TimeSpan . Zero , DispatcherPriority . Background , Dispatcher . CurrentDispatcher )
{
{
}
}
/// <summary>
/// <summary>
/// Creates a timer that uses the UI thread's Dispatcher2 to
/// Creates a timer that uses <see cref="Avalonia.Threading.Dispatcher.CurrentDispatcher"/> to
/// process the timer event at the specified priority.
/// process the timer event at the specified priority.
/// </summary>
/// </summary>
/// <param name="priority">
/// <param name="priority">The priority to process the timer at.</param>
/// The priority to process the timer at.
public DispatcherTimer ( DispatcherPriority priority )
/// </param>
: this ( TimeSpan . Zero , priority , Dispatcher . CurrentDispatcher )
public DispatcherTimer ( DispatcherPriority priority ) : this ( Threading . Dispatcher . UIThread , priority ,
TimeSpan . FromMilliseconds ( 0 ) )
{
{
}
}
/// <summary>
/// <summary>
/// Creates a timer that uses the specified Dispatcher2 to
/// Creates a timer that uses the specified <see cref="Avalonia.Threading.Dispatcher"/> to
/// process the timer event at the specified priority.
/// process the timer event at the specified priority.
/// </summary>
/// </summary>
/// <param name="priority">
/// <param name="priority">The priority to process the timer at.</param>
/// The priority to process the timer at.
/// <param name="dispatcher">The dispatcher to use to process the timer.</param>
/// </param>
public DispatcherTimer ( DispatcherPriority priority , Dispatcher dispatcher )
/// <param name="dispatcher">
: this ( TimeSpan . Zero , priority , dispatcher )
/// The dispatcher to use to process the timer.
/// </param>
internal DispatcherTimer ( DispatcherPriority priority , Dispatcher dispatcher ) : this ( dispatcher , priority ,
TimeSpan . FromMilliseconds ( 0 ) )
{
{
}
}
/// <summary>
/// <summary>
/// Creates a timer that uses the UI thread's Dispatcher2 to
/// Creates a timer that uses the specified <see cref="Avalonia.Threading.Dispatcher"/> to
/// process the timer event at the specified priority after the specified timeout.
/// process the timer event at the specified priority after the specified timeout.
/// </summary>
/// </summary>
/// <param name="interval">
/// <param name="interval">The interval to tick the timer after.</param>
/// The interval to tick the timer after.
/// <param name="priority">The priority to process the timer at.</param>
/// </param>
/// <param name="dispatcher">The dispatcher to use to process the timer.</param>
/// <param name="priority">
public DispatcherTimer ( TimeSpan interval , DispatcherPriority priority , Dispatcher dispatcher )
/// The priority to process the timer at.
/// </param>
/// <param name="callback">
/// The callback to call when the timer ticks.
/// </param>
public DispatcherTimer ( TimeSpan interval , DispatcherPriority priority , EventHandler callback )
: this ( Threading . Dispatcher . UIThread , priority , interval )
{
{
if ( callback = = null )
ArgumentNullException . ThrowIfNull ( dispatcher ) ;
DispatcherPriority . Validate ( priority , "priority" ) ;
if ( priority = = DispatcherPriority . Inactive )
{
throw new ArgumentException ( "Specified priority is not valid." , nameof ( priority ) ) ;
}
var ms = interval . TotalMilliseconds ;
if ( ms < 0 )
{
{
throw new ArgumentNullException ( nameof ( callback ) ) ;
throw new ArgumentOutOfRangeException ( nameof ( interval ) ,
"TimeSpan period must be greater than or equal to zero." ) ;
}
}
if ( ms > int . MaxValue )
{
throw new ArgumentOutOfRangeException ( nameof ( interval ) ,
"TimeSpan period must be less than or equal to Int32.MaxValue." ) ;
}
_d ispatcher = dispatcher ;
_ priority = priority ;
_ interval = interval ;
}
/// <summary>
/// Creates a timer that uses <see cref="Avalonia.Threading.Dispatcher.CurrentDispatcher"/> to
/// process the timer event at the specified priority after the specified timeout and with
/// the specified handler.
/// </summary>
/// <param name="interval">The interval to tick the timer after.</param>
/// <param name="priority">The priority to process the timer at.</param>
/// <param name="callback">The callback to call when the timer ticks.</param>
/// <remarks>This constructor immediately starts the timer.</remarks>
public DispatcherTimer ( TimeSpan interval , DispatcherPriority priority , EventHandler callback )
: this ( interval , priority , Dispatcher . CurrentDispatcher , callback )
{
}
/// <summary>
/// Creates a timer that uses the specified <see cref="Avalonia.Threading.Dispatcher"/> to
/// process the timer event at the specified priority after the specified timeout and with
/// the specified handler.
/// </summary>
/// <param name="interval">The interval to tick the timer after.</param>
/// <param name="priority">The priority to process the timer at.</param>
/// <param name="dispatcher">The dispatcher to use to process the timer.</param>
/// <param name="callback">The callback to call when the timer ticks.</param>
/// <remarks>This constructor immediately starts the timer.</remarks>
public DispatcherTimer ( TimeSpan interval , DispatcherPriority priority , Dispatcher dispatcher , EventHandler callback )
: this ( interval , priority , dispatcher )
{
ArgumentNullException . ThrowIfNull ( callback ) ;
Tick + = callback ;
Tick + = callback ;
Start ( ) ;
Start ( ) ;
@ -252,33 +289,6 @@ public partial class DispatcherTimer
/// </summary>
/// </summary>
public object? Tag { get ; set ; }
public object? Tag { get ; set ; }
internal DispatcherTimer ( Dispatcher dispatcher , DispatcherPriority priority , TimeSpan interval )
{
if ( dispatcher = = null )
{
throw new ArgumentNullException ( nameof ( dispatcher ) ) ;
}
DispatcherPriority . Validate ( priority , "priority" ) ;
if ( priority = = DispatcherPriority . Inactive )
{
throw new ArgumentException ( "Specified priority is not valid." , nameof ( priority ) ) ;
}
if ( interval . TotalMilliseconds < 0 )
throw new ArgumentOutOfRangeException ( nameof ( interval ) , "TimeSpan period must be greater than or equal to zero." ) ;
if ( interval . TotalMilliseconds > Int32 . MaxValue )
throw new ArgumentOutOfRangeException ( nameof ( interval ) ,
"TimeSpan period must be less than or equal to Int32.MaxValue." ) ;
_d ispatcher = dispatcher ;
_ priority = priority ;
_ interval = interval ;
}
private void Restart ( )
private void Restart ( )
{
{
lock ( _ instanceLock )
lock ( _ instanceLock )