10
votes

Comment exécuter du code dans le fil de l'interface graphique?

J'ai un SystemWatcher de fichiers qui réagit sur l'événement modifié.

Je souhaite ouvrir le fichier, lire son contenu l'affiche dans une zone de texte et masquer la fenêtre contextuelle créée après 1 seconde. Le code fonctionne presque mais quelque chose échoue lors de la masquage de la popup.

Voici un extrait du code: xxx

Comme vous pouvez le constater, j'utilise le Invoquer Pour définir le texte car l'événement est dans un fil différent (FileSystemwatcher). Mais pour masquer les fenêtres, l'extensionnotifyicon_onhidewindow () n'est pas exécuté dans le fil de l'interface graphique. Comment puis-je l'exécuter dans le fil de l'interface graphique?


0 commentaires

6 Réponses :


4
votes

Ceci vous donnera le répartiteur de la fenêtre: xxx

tant que vous l'obtenez sur le thread Windows.


1 commentaires

Pour l'obtenir à partir d'un autre thread, essayez l'application.current.dispatcher.invoke (nouvelle action (() => {Méthode ()}));



2
votes

Utilisez CONTROL.INVOKE

   txtLog.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() {
        this.txtLog.Text = dataToDisplay;
        extendedNotifyIcon_OnShowWindow();
        Thread threadToClosePopup = new Thread(new ThreadStart((Action)delegate() { 
            Thread.Sleep(1000); 

            extendedNotifyIcon.Invoke(extendedNotifyIcon_OnHideWindow);
   }));
        threadToClosePopup.Start();
    });


0 commentaires

11
votes

Pour exécuter la méthode ExtendednotiCon_onhideWindow sur le thread de l'interface graphique Utilisez le Dispatcher comme vous l'avez fait pour le montrer. xxx


0 commentaires

1
votes

juste envelopper ExtendueNotificon_onhidewindow (); dans un Dispatcher.invoke ()

Mais je préférerais le faire (tout iM xaml) à l'aide d'une animation et avec un événement d'événement qui déclenche sur l'événement Timeline.cablé.


1 commentaires

Je suis vraiment nouveau à WPF, il suffit de modifier un code existant. Le code dans la pop up XAML et en fait apparaissent lorsque la souris quitte le conteneur. Mais maintenant, je dois ajouter quelque chose à l'apparaître à partir du code et de la pop-dépose du code sans supprimer le comportement initial. +1 pour l'idée



0
votes

Le problème est que ExtendednotiCon_onhidewindow code> est exécuté sur un fil autre que le fil de l'interface utilisateur. Vous devrez utiliser le répartiteur code> pour cette pièce aussi. En outre, je ne créerais pas de fil dédié juste d'attendre une seconde. Vous pouvez facilement refroidir cette partie dans un system.threading.Timer code>. Voici ma version refouturée.

txtLog.Dispatcher.Invoke(
    (Action)(() =>
        {
            txtLog.Text = dataToDisplay;
            extendedNotifyIcon_OnShowWindow(); 
            new Timer(
                (state) =>
                {
                    button1.Dispatcher.BeginInvoke(
                        (Action)(() =>
                            {
                              extendedNotifyIcon_OnHideWindow(); 
                            }), null);
                }, null, 1000, Timeout.Infinite);
        }));


0 commentaires

29
votes

Ceci fonctionne bien pour WPF avec mvvm . xxx

Ceci va pas ne fonctionne pas de manière cohérente échouera si nous sommes à l'intérieur d'un gestionnaire pour des extensions réactives): xxx

supplémentaire pour les experts: la raison?

par conception, tout fil peut avoir un Thread Dispatcher couplé avec elle, voir MSDN: Classe Dispatcher .

Si nous référons Dispatcher.CurrentDispatcher à partir de n'importe quel thread, il créera un nouveau thread de répartiteur, distinct du WPF officiel. Fil du répartiteur de l'UI. Lorsque nous essayons d'exécuter du code sur ce fil de répartiteur nouvellement créé, WPF lancera car ce n'est pas le thread officiel du répartiteur de l'interface utilisateur.

La solution consiste à utiliser toujours application.Current.dispatcher.invoke () ou application.current.dispatcher.begininvoke () . Voir Quelle est la différence entre Invoke () et Begininvoke () . < / P>


Mise à jour 2020-05-02: Il est possible d'exécuter une application WPF avec plusieurs threads de répartiteur UI WPF. Je travaille avec une énorme application WPF qui le fait. Il est délicat de le faire fonctionner, mais une fois que cela fonctionne - c'est incroyable et l'application entière exécute une commande de magnitude plus rapide car il existe plusieurs threads de répartiteur de l'UI. Heureux de répondre aux questions à ce sujet.


testé sur:

  • wpf
  • .NET 4.5
  • .NET 4.6
  • .NET 4.61


2 commentaires

Tu as sauvé ma journée!


@Jan, vous êtes la bienvenu. Mise à jour de ce message pour ajouter la raison pour laquelle cela se produit.