[WPF - NET 7.0] - El control DispatcherTimer

Descripción general:

XAML no admite ninguna característica de temporizador y WPF no tiene un control o clase de temporizador. La clase DispatchTimer definida en el espacio de nombres System.Windows.Threading se usa para agregar la funcionalidad del temporizador en WPF.

En WinForms hay un control llamado Timer que puede ejecutar una acción repetidas veces dentro de un intervalo de tiempo. En WPF, tenemos el control DispatcherTimer . que hace casi lo mismo,

Lo interesante de DispatchTimer es que se ejecuta en la cola de Dispatcher que se ejecuta en un subproceso independiente del que ejecuta nuestra aplicación. Esto significa que cuando el temporizador se ejecuta y activa el evento Tick, puedo dibujar en la pantalla con cualquier retraso, lo que nos da la oportunidad de hacer cualquier tipo de animación y actualización de pantalla según sea necesario.

La clase DispatcherTimer trabaja especificando un intervalo y suscribiéndolo al evento Tick que ocurrirá cada vez que se cumpla el intervalo. El DispatcherTimer no comienza hasta que llamas al método Start() o estableces la propiedad IsEnabled a verdadero.


↑↑↑

Ejemplo donde usamos DispatcherTimer para crear un reloj digital:

Código XAML


<Window  x:Class="DispatcherTimeMainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfPruebaDispatcherTime"
        mc:Ignorable="d"
        Title="Wpf Prueba Dispatcher Time - Main Window"
        Height="150" Width="300">
    <Grid>
        <TextBlock   x:Name="TextBlockTime" 
                    FontSize="48" 
                    HorizontalAlignment="Center" VerticalAlignment="Center" 
                    Text="00:00:00"/>
        
    </Grid>
</Window>

Código Vb.Net


Class DispatcherTimeMainWindow 

    Public Sub New()

        ' Esta llamada es exigida por el diseñador. 
        InitializeComponent()

        ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 
        '---------------------------------------------------------- 
        ' valor para el timer 
        '---------------------------------------------------------- 
        Call InicializarLosTimer()

    End Sub 

#Region "Timer[System.Windows.Threading.DispatcherTimer]" 
    ' 
    ''' <summary> 
    ''' Se dispara cada segundo para simular el movimiento del secudero de un reloj 
    ''' </summary> 
    Private TimerUnSegundo As New System.Windows.Threading.DispatcherTimer 

    ''' <summary> 
    ''' Asigna los valores iniciales y define los eventos Tick del[DispatcherTimer] 
    ''' </summary> 
    Private Sub InicializarLosTimer()

        '--------------------------------------------- 
        ' Definir los eventos como en C#" 
        '--------------------------------------------- 
        '' A) El objeto que dispara el evento 
        '    Private TimerUnSegundo As New System.Windows.Threading.DispatcherTimer 
        ' 
        '' B) Definir el evento 
        ''   [TimerUnSegundo.Tick] es el nombre del evento 
        ''   [AddressOf TimerUnSegundo_Tick] apunta a la función 
        ''    que tiene el código del escuchador del evento 
        AddHandler TimerUnSegundo.Tick,AddressOf TimerUnSegundo_Tick 
        ' 
        '' C) La función escuchador del evento 
        ' Private Sub TimerUnSegundo_Tick(sender As Object, e As EventArgs) 
        '--------------------------------------------- 

        ' Asignar el intervalo 
        TimerUnSegundo.Interval = TimeSpan.FromSeconds(1)' 1 segundo 
        ' Poner en marcha el timer 
        TimerUnSegundo.Start()
    End Sub 

    ''' <summary> 
    ''' Escuchador del evento[Tick] del objeto[TimerUnSegundo] 
    ''' Se dispara cada segundo para simular el movimiento del secudero de un reloj 
    ''' </summary> 
    Private Sub TimerUnSegundo_Tick(sender As Object,e As EventArgs)

        ' Parar el timer y hacer las operaciones 
        'Me.TimerUnSegundo.Stop() 

        TextBlockTime.Text = DateTime.Now.ToLongTimeString()

        ' Encender el timer 
        'TimerUnSegundo.Start() 

        '-------------------------------------------------------------- 
        ' Obligar al CommandManager a generar el evento RequerySuggested 
        CommandManager.InvalidateRequerySuggested()
    End Sub 

    ''' <summary> 
    ''' Destruir los objeto timer usados 
    ''' </summary> 
    Private Sub DisposeTimer()
        ' Detener los timer 
        Me.TimerUnSegundo.Stop()
        ' Destruir los objetos timer usados 
        TimerUnSegundo = Nothing 
    End Sub 

#End Region 

End Class 

Imagen del resultado

Naturalmente el DispatcherTimer puede trabajar con intervalos más pequeños o mayores. Por ejemplo tu podrías desear que ocurriera cada 30 segundos o cada 5 minutos - para esto usa el método TimeSpan.From , usando FromSeconds (para segundos) o FromMinutes (para minutos), o crea un nueva instancia TimeSpan que se adapte completamente a tus necesidades.


↑↑↑

Resumen

  • Hay muchas ocasiones donde necesitas que algo ocurra a intervalos de tiempo dados y es muy simple de conseguir usando la clase DispatcherTimer
  • MSDN dice que No se garantiza que los temporizadores se ejecuten exactamente cuando se produce el intervalo de tiempo. Se asegura que el evento Tick no se lanzará nunca demasiado pronto, pero no se puede asegurar que no se retrasará ligeramente. Esto se debe a que las operaciones DispatcherTimer  se colocan en la cola Dispatcher como otras operaciones. Cuando se ejecuta la operación  DispatcherTimer depende de los demás trabajos de la cola y sus prioridades. Sin embargo, en la mayoría de las ocasiones, el DispatcherTimer es lo suficientemente preciso.
  • Si necesitas que tu temporizador tenga una mayor prioridad en la cola, puedes establecer la DispatcherPriority (Prioridad) enviando uno de los valores a través de la prioridad del DispatcherTimer. Más información acerca de ello puedes encontrarlo en este artículo MSDN.