How to execute code in a GUI thread?

I have a FileSystemWatcher that responds to a Changed event.

I want to open a file, read its contents, display it in a text box and hide the popup that was created after 1 second. The code almost works, but something fails to hide the popup.

Here is the code snippet:

       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_OnHideWindow();
       }));
            threadToClosePopup.Start();
        });

As you can see, I use Invoke to set the text, because the event is in a different thread (FileSystemWatcher). But to hide windows, extended NotifyIcon_OnHideWindow () is not executed in the GUI thread. How can I execute it in a GUI thread?

+3
source share
6

extendedNotifyIcon_OnHideWindow , Dispatcher, .

Thread threadToClosePopup = new Thread(new ThreadStart((Action)delegate() { 
  Thread.Sleep(1000); 
  txtLog.Dispatcher.Invoke(
    DispatcherPriority.Normal,
    (Action)() => extendedNotifyIcon_OnHideWindow());
}));
+9

WPF MVVM.

Application.Current.Dispatcher.Invoke(
    () =>
    {
         // Code to run on the GUI thread.
    });

( , ):

Dispatcher.CurrentDispatcher.Invoke(
    () =>
    {
         // Fails if we are inside a handler for Reactive Extensions!
    });

: ?

, . MSDN: Dispatcher Class.

Dispatcher.CurrentDispatcher , , WPF. , WPF , .

, Application.Current.Dispatcher.Invoke() Application.Current.Dispatcher.BeginInvoke(). . Invoke() BeginInvoke().


:

  • WPF
  • .NET 4.5
  • .NET 4.6
  • .NET 4.61
+9

:

Dispatcher.CurrentDispatcher

Windows.

+2

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

extendedNotifyIcon_OnHideWindow(); Dispatcher.Invoke()

But I would prefer to do this (all im XAML) using animation, and with EvenTrigger, which fires the TimeLine.Completed event.

+1
source

The problem is what extendedNotifyIcon_OnHideWindowruns on a thread other than the user interface thread. You also need to use Dispatcherfor this part. Also, I would not create a dedicated thread to wait one second. You can easily reorganize this part into System.Threading.Timer. Here is my updated version.

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

Source: https://habr.com/ru/post/1764900/


All Articles