2010-02-13 14 views
21

Explique la diferencia entre "DispatcherTimer" y "un temporizador normal" que @Kent Boogaart quiso utilizar en una aplicación WPF de multiproceso como supervisor de tareas en este tema:DispatcherTimer frente a un temporizador regular en la aplicación WPF para un programador de tareas

Advice needed for multi-threading strategy for WPF application

en los comentarios de uno de los correos (cita):

-Si todo el DispatcherTimer hace es inicio a otro hilo, ¿cuál es el punto de utilizar la DispatcherTimer? .... esos hilos no necesitan iniciarse en el hilo de la interfaz de usuario. Simplemente podría usar un temporizador regular y evitar la interrupción total de la interfaz de usuario

¿Qué significa "un temporizador normal"? ¿Cómo difieren ("DispatcherTimer" y "Timer regular") con respecto a su impacto en la UI?

(Hasta leer este post pensé en DispatcherTimer como una forma natural de la utilización de temporizadores en WPF. ¿Qué es los casos en que esto no es cierto?)

Respuesta

39

DispatcherTimer es el temporizador normal. Dispara su evento Tick en el hilo de la interfaz de usuario, puede hacer lo que quiera con la interfaz de usuario. System.Timers.Timer es un temporizador asincrónico, su evento Elapsed se ejecuta en una cadena de subprocesos. Debe tener mucho cuidado con su controlador de eventos, no tiene permitido tocar ningún componente de la interfaz de usuario o variables de datos. Y deberá usar la instrucción de bloqueo siempre que acceda a miembros de la clase que también se utilizan en el hilo de la interfaz de usuario.

En la respuesta vinculada, la clase del temporizador era más apropiada porque el OP intentaba ejecutar código de forma asíncrona a propósito.

+0

nota que 'tocar' incluye el establecimiento de propiedades ViewModel MVVM por lo que cuando el uso de un DispatcherTimer usted está muy bien, pero con un temporizador que no se puede incluso hacer que –

26

El evento Tick del temporizador regular se dispara realmente en la secuencia donde se creó el temporizador, por lo que en el evento tick, para acceder a cualquier elemento con la interfaz de usuario, deberá pasar por dispatcher.begininvoke como se menciona a continuación.

RegularTimer_Tick(object sender, EventArgs e) 
{ 
    txtBox1.Text = "count" + i.ToString(); 
    // error can not access 
    // txtBox1.Text property outside dispatcher thread... 

    // instead you have to write... 
    Dispatcher.BeginInvoke((Action)delegate(){ 
     txtBox1.Text = "count " + i.ToString(); 
    }); 
} 

En caso de Dispatcher temporizador, puede acceder a elementos de la interfaz sin hacer comenzar invocar o invocar como sigue ...

DispatcherTimer_Tick(object sender, EventArgs e) 
{ 
    txtBox1.Text = "Count " + i.ToString(); 
    // no error here.. 
} 

DispatcherTimer simplemente proporciona la conveniencia sobre temporizador normal para acceder a objetos de interfaz de usuario sencilla.

+1

Gracias por los ejemplos de código, 1 – rem

+0

es Temporizador despachador usando Invoke o BeginInvoke? –

+0

Basado en la fuente aquí, DispatcherTimer está utilizando BeginInvoke, razón por la cual la cola del despachador tiene un mecanismo de invocación basado en la prioridad. http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/DispatcherTimer.cs,d2a05f6b09eee858 –

14

Con .NET 4.5 también puede crear un delegado async para su temporizador si necesita utilizar la nueva funcionalidad .NET 4.5 await.

 var timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(20); 
     timer.Tick += new EventHandler(async (object s, EventArgs a) => 
     { 
      Message = "Updating..."; 
      await UpdateSystemStatus(false); 
      Message = "Last updated " + DateTime.Now;    
     }); 
     timer.Start(); 
+0

esto también puede ser de interés (mi propia pregunta en busca de un DispatcherTimer amigable y asincrónico) http://stackoverflow.com/questions/12442622/async-aware-friendly-dispatchertimer-wrapper-subclass/12442719 # 12442719 –

Cuestiones relacionadas