DispatcherTimer vs régulière de la Minuterie en application WPF, pour un planificateur de tâches

Veuillez expliquer la différence entre" DispatcherTimer " et "a regular Timer" que @Kent Boogaart a voulu utiliser dans une application WPF multithreading comme un sheduler de tâche dans ce sujet:

conseils nécessaires pour la stratégie multi-threading pour l'application WPF

dans les commentaires de l'un des postes (citation):

- si le répartiteur ne fait que lancer un autre fil, qu'est-ce que le point de l'utilisation de la Minuterie? ....ces threads n'ont pas besoin d'être lancés sur le thread de L'interface utilisateur. Vous pourriez juste utiliser un minuteur régulier et éviter d'interrompre L'UI tout à fait

Qu'entend-on par "Horaire régulier"? En quoi ("DispatcherTimer "et" a regular Timer") diffèrent-ils quant à leur incidence sur L'assurance-chômage?

(Jusqu'à la lecture de ce post, j'ai pensé à DispatcherTimer comme une façon naturelle d'utiliser les minuteries dans WPF. Ce qui est le cas lorsque ce n'est pas vrai?)

22
demandé sur Community 2010-02-13 22:57:52

3 réponses

DispatcherTimer est la minuterie habituelle. Il lance son évènement Tick sur le thread de L'interface utilisateur, vous pouvez faire tout ce que vous voulez avec L'interface utilisateur. Système.Minuterie.La minuterie est une minuterie asynchrone, son événement écoulé tourne sur un thread pool. Vous devez être très prudent dans votre gestionnaire d'événements, vous n'êtes pas autorisé à toucher tout composant de l'INTERFACE utilisateur ou des données variables liées. Et vous aurez besoin d'utiliser la déclaration de verrouillage où que vous accédiez aux membres de la classe qui sont également utilisés sur le thread de L'interface utilisateur.

Dans la réponse liée, la classe de minuterie était plus appropriée parce que L'OP essayait d'exécuter le code de manière asynchrone volontairement.

40
répondu Hans Passant 2015-06-15 10:14:58

L'événement Tick du Timer régulier est en fait allumé sur le thread où le Timer a été créé, donc dans l'événement tick, afin d'accéder à n'importe quoi avec L'UI, vous devrez passer par le répartiteur.begininvoke tel que mentionné ci-dessous.

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();
    });
}

dans le cas de Dispatcher Timer, vous pouvez accéder aux éléments de L'UI sans faire appel à begin ou invoquer comme suit...

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

DispatcherTimer juste fournit la commodité par rapport à la minuterie régulière d'accès Les objets d'INTERFACE utilisateur facilement.

26
répondu Akash Kava 2010-02-14 09:32:36

avec .NET 4.5 vous pouvez également créer un async délégué pour votre minuterie si vous avez besoin d'utiliser la nouvelle fonctionnalité .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();
14
répondu Simon_Weaver 2012-09-15 20:45:52