WPF France

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille

DispatcherTimer : Qu'est-ce-que c'est ?

Envoyer Imprimer PDF
Note des utilisateurs: / 3
MauvaisTrès bien 

 

Un Timer est un objet permettant de déclencher une action à intervalle régulier. C'est une sorte de minuterie.

En WPF, il existe un timer bien particulier, nommé DispatcherTimer permettant d'effectuer ces actions sur le Thread UI.

Dans cet article, nous l'étudions plus en détails !



Pourquoi utiliser un DispatcherTimer ?

Vous le savez surement, en WPF il y a un thread principal sur lequel le rendu graphique est effectué. Aussi, si vous souhaitez accéder ou modifier un élément de l'interface graphique alors il faut être sur ce Thread. C'est une obligation imposée par le framework.

Le DispatcherTimer permet ainsi de déclencher un Timer qui sera exécuté sur le Thread principal. Il pourra ainsi accéder aux éléments de l'interface graphique.

Prenons un exemple concret afin d'illustrer cette théorie : nous allons créer une application toute simple permettant d'incrémenter une valeur toutes les secondes. C'est une sorte de compte à rebour inversé un chronométre (Merci Boris) !
DispatcherTimerScreenShot

Si nous ne connaisons pas les Timers alors l'idée qui vient à notre esprit et de bloquer le Thread en utilisant la méthode Thread.Sleep de cette façon :
while (_valeurInt < 40)
{
    Thread.Sleep(TimeSpan.FromSeconds(1));
    _valeurInt++;
    _valeur.Text = _valeurInt.ToString(CultureInfo.InvariantCulture);
}
L'inconvénient est que ce code est executé sur le thread principal. Ainsi, jusqu'a ce que le compte à rebour soit terminé (ici à la valeur 40), l'interface sera figée (la méthode Thread.Sleep endort complétement le Thread). L'utilisateur aura alors l'impression que l'interface se fige pendant 40 secondes et verra apparaitre finalement le chiffre 40.

Comment utiliser le DispatcherTimer ?

L'idée est alors d'utiliser le DispatcherTimer pour mettre à jour la valeur. Pour cela il faut définir un intervalle de temps : c'est l'écart qu'il y aura entre chaque execution. Celui-ci est représenté sous la forme de la propriété Interval. Attention, cette valeur n'est pas précise et il faut recourir à d'autres méchanismes si l'on souhaite une précision extrême.

La classe DispatcherTimer définit aussi un événement appelé Tick : il sera déclenché à la fin de chaque intervalle de temps et est executé sur le Dispatcher. C’est donc à lui qu’il faut s’abonner pour définir le traitement à effectuer.

 

Une instance de DispatcherTimer défini aussi les méthodes start et stop permettant de le démarrer et de l’arrêter.

Voici alors l'exemple complet reproduisant notre compte à rebour inversé mais sans blocage de l'interface utilisateur :

private void StopTimer()
{
    if (timer != null)
    {
        //Arrêt du timer
        timer.Stop();
    }
    timer = null;
}
 
 
private void StartTimer()
{
    //Création du timer
    if (timer == null)
    {
        timer = new DispatcherTimer(DispatcherPriority.ContextIdle);
    }
 
    //Déclenchement toutes les secondes
    timer.Interval = TimeSpan.FromSeconds(1);
 
    //La méthode TimerTick sera appelée toutes les secondes
    timer.Tick += TimerTick;
 
    //On démarre le Timer
    timer.Start();
 
}
 
private int _valeurInt = 0;
void TimerTick(object sender, EventArgs e)
{
    //Incrémentation de la valeur
    _valeurInt++;
 
    //Changement du contrôle
    _valeur.Text = _valeurInt.ToString(CultureInfo.InvariantCulture);
}

Aller plus loin avec le DispatcherTimer

Une fois que l’on maîtrise bien ces concepts de base, on peut aller encore plus loin en définissant une priorité à utiliser pour l’execution des gestionnaires d’événement attaché à Tick.

Cela est fait via le constructeur :

timer = new DispatcherTimer(DispatcherPriority.ContextIdle);

 

Aussi, il est possible d’associer un objet à un timer qui pourra être retrouvé à l’éxecution de la méthode de traitement. C’est une façon de passer des paramétres. Voici un exemple :

//Définition de la valeur de Tag
 timer.Tag = "Une valeur";
 
//Plus loin dans le gestionnaire d'événement de Tick
 void TimerTick(object sender, EventArgs e)
 {
     var timer = sender as DispatcherTimer;
     var valeur = timer.Tag;
     Console.WriteLine("Valeur retrouvée : "valeur);
 }

 

En espérant que cela vous éclairera Sourire

 

Bon code !

Commentaires (0)
Mise à jour le Mercredi, 04 Janvier 2012 08:48  

Partagez


Article au hasard

  • Dans cet article nous allons voir comment créer facilement une petite application de conversion d'un fichier XAML représentant un contrôle en un fichier image. Cela est aussi une bonne introduction pour ceux voulant découvrir la création d'un screenshot d'un contrôle en WPF. Les points abordés sont donc : Comment créer un screenshot d'un contrôle dans une taille bien précise (vous spécifiez la taille voulue), Comment charger un fichier XAML externe dans une application WPF...
    Lire la suite...