Dispatcher.Invoke有时不会被调用

本文关键字:调用 Invoke Dispatcher | 更新日期: 2023-09-27 18:01:36

我的应用程序需要不时显示气球通知。我通过执行创建NotifyIconActionDispatcher.Invoke()执行此操作,显示气球通知,然后处置系统托盘图标。

public abstract class Foo {
    void Bar() {
        MainWindow.ShowTrayNotification(ToolTipIcon.Info, "Hello There!", "Balloon text here.");
    }
}
public partial class MainWindow : Window {
    static Dispatcher dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
    public static void ShowTrayNotification(ToolTipIcon icon, string title, string text) {
        dispatcher.Invoke(new Action(() => {
            //anything here is not run
            UIHelper.ShowTrayNotification(icon, title, text); //static method
        }));
        //anything here is also not called if dispatcher.Invoke() is not run
    }
}

但是,有时Dispatcher.Invoke没有运行。日志记录就在它之前停止,并且在InvokeAction内部不会发生日志记录。

奇怪的是,当我触发电脑关机时,Invoke突然启动(显示通知(并正常进行(执行关机前的回调(。

我试着执行"调试">"Windows">"线程",但在"调试"模式下没有出现问题,所以我找不到导致UI线程阻塞的原因。

造成这种情况的原因是什么?我该如何解决?

更新

我尝试了以下操作,但没有成功:

  • 我把它改成了BeginInvoke

  • 我添加了DispatcherPriority.Send

更新2

public class UIHelper
{
    public static void ShowTrayNotification(ToolTipIcon icon, string title, string text) {
        NotifyIcon trayIcon = new NotifyIcon();
        trayIcon.Icon = MyApp.Properties.Resources.myIcon;
        trayIcon.Text = "MyApp";
        trayIcon.BalloonTipClosed += TrayNotificationClosed;
        trayIcon.Visible = true;
        trayIcon.ShowBalloonTip(5000, title, text, icon);
    }
    static void TrayNotificationClosed(object sender, EventArgs e) {
        ((NotifyIcon)sender).Visible = false;
        ((NotifyIcon)sender).Icon = null;
        ((NotifyIcon)sender).Dispose();
        sender = null;
    }
}

Dispatcher.Invoke有时不会被调用

这样试试:

public partial class MainWindow : Window
    {
        static Dispatcher dispatcher = System.Windows.Application.Current.Dispatcher;
        public static void ShowTrayNotification(ToolTipIcon icon, string title, string text)
        {
            if (dispatcher != null && !dispatcher.CheckAccess())
            {
                dispatcher.Invoke(() => ShowTrayNotification(icon, title, text));
                return;
            }
            UIHelper.ShowTrayNotification(icon, title, text);
        }
    }

另请参阅Dispatcher.CurrentDispatcher与Application.Current.Dispatcher