2011-09-06 1 views
1

Dans .NET4.0 WPF, je souhaite afficher un drawingPath sur un canevas à l'aide d'un fil d'arrière-plan. Le ConsumerJob suivant s'exécute correctement en arrière-plan et interroge une file de points à dessiner. J'utilise un Dispatcher pour modifier le canevas sur le thread principal et il est rendu correctement. Cependant, je m'attendrais à ce que ce code affiche chaque segment un à la fois au fur et à mesure que chaque fichier children.add est invoqué (comme une animation). Ce qui se passe, c'est que tout l'affichage est rendu à la fois et pas un segment à la fois. Comment est-ce que je devrais modifier le code pour rendre l'affichage pendant que les enfants sont ajoutés un à la fois?canvas non mis à jour en temps réel par thread d'arrière-plan

public void ConsumerJob() 
    { 

     while (true) 
     { 
      PointsD pt = (PointsD)queue.Consume(); 
      displayQueue.Enqueue(pt); 

      pt = Scale(pt); 

      this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
       (ThreadStart)delegate() 
       { 
        Path drawingPath = new Path(); 
        StreamGeometry streamingGeometry = new StreamGeometry(); 
        drawingPath.Stroke = Brushes.Black; 
        drawingPath.StrokeThickness = 0.5; 

        using (StreamGeometryContext ctx = streamingGeometry.Open()) 
        { 
          ctx.BeginFigure(new Point(pt.x0, pt.y0), false, false); 
          ctx.LineTo(new Point(pt.x1, pt.y1), true, false); 
        } 

        streamingGeometry.Freeze(); 
        drawingPath.Data = streamingGeometry; 

        this.Children.Add(drawingPath); 

       } 
       ); 

     } 
+1

Autre option aurait pu être d'utiliser un BackgroundWorker, il fournit 3 événements tels que DoWork() (avec seulement le code délégué ci-dessus), ProgressNotified() (ajout de l'enfant dans la toile) et WorkCompleted() le bit suivant RunAsync() du bgworker), ce qui lui donne l'impression que c'est un thread qui travaille éternellement et qui notifie de manière synchrone le thread UI pour ajouter de nouveaux bits au canvas en tant qu'animation. –

Répondre

1

Dispatcher.BeginInvoke est asynchrone, vous avez essayé son homologue synchrone Invoke? Cela devrait au moins faire en sorte que tous les délégués mis en file d'attente soient exécutés dans le bon ordre, mais ils ne sont pas sûrs de la date et de l'heure.

Vous pouvez également essayer une DispatcherPriority supérieure en plus de cela.

+0

Merci beaucoup. J'ai changé BeginInvoke en Invoke et ça fonctionne maintenant parfaitement. Le chemin est affiché en temps réel. Je suis toujours surpris à ce sujet comme vous le dites, pas clair pourquoi cela affecte le calendrier. Utile si quelqu'un a des indices. –

+0

@ChristopheBraun: Eh bien, BeginInvoke revient immédiatement après la mise en file d'attente du délégué, donc, selon toute vraisemblance, toutes les mises à jour sont mises en file d'attente et exécutées en un cycle, vous laissant un saut. Invoke attend le délégué en cours d'exécution. Voir aussi la [référence du modèle de threads] (http://msdn.microsoft.com/en-us/library/ms741870.aspx), il contient plus d'informations sur le fonctionnement de cette file d'attente. –

Questions connexes