Мое приложение должно время от времени показывать уведомления о воздушном шаре. Я делаю это через Dispatcher.Invoke()
, который выполняет Action
, который создает NotifyIcon
, отображает уведомление о шаре, а затем отображает значок в системном трее.Dispatcher.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
не запускается. Ведение журналов останавливается прямо перед ним, и никаких ошибок не происходит внутри Invoke
Action
.
Что странно в том, что когда я запускаю остановку ПК, внезапно запускается Invoke
(уведомление отображается) и работает нормально (мои обратные вызовы перед выключения выполняются).
Я попытался выполнить Debug> Windows> Threads, но проблема не возникает в режиме отладки, поэтому я не могу найти то, что вызывает блокировку потока пользовательского интерфейса.
Что вызывает это и как я могу его исправить?
UPDATE
Я попытался следующие, и они не работали:
Я изменил его
BeginInvoke
.Я добавил
DispatcherPriority.Send
.
UPDATE 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;
}
}
Как о вызове диспетчера на сам объект? например, 'UIHelper.Dispatcher.Invoke ...' Или вы можете попробовать поставить «MessageBox» перед диспетчером. Попробуйте проверить, работает ли даже этот метод. Это всего лишь предложение. –
Dispatcher.Invoke() будет тупиком, когда поток пользовательского интерфейса вашего приложения занят чем-то другим. Используйте окно Debug> WIndows> Threads debugger для диагностики. –
@ JakubLokša 'dispatcher.Invoke' никогда не запускается. Я использую диспетчера в 'MainWindow', чтобы убедиться, что' NotifyIcon' в 'UIHelper' создан в основном потоке пользовательского интерфейса, иначе он не отображается. – Obay