WPF中使用ToastNotifications返回2个异常,如何解决?
问题原因
- 核心问题是
SqlTableDependency的OnChanged事件默认在后台非UI线程触发,WPF规定所有UI相关操作(包括Toast通知显示、访问Application.Current.MainWindow窗口对象)都必须在创建UI资源的主线程执行,直接在事件回调中操作Notifier触发了跨线程访问UI资源的异常。 - 额外优化点:每次触发
OnChanged事件都新建Notifier实例,重复创建销毁通知对象会带来不必要的资源开销,也容易引发引用释放类异常。
解决步骤
- 将Notifier改为全局单例,仅在程序启动(如MainWindow构造函数)时初始化一次,避免重复创建。
- 显式将通知操作封送到UI线程执行,从根源避免跨线程访问异常。
修正后代码示例
全局初始化Notifier
// 全局声明Notifier private Notifier _notifier; public MainWindow() { InitializeComponent(); // 窗口初始化时仅创建一次Notifier _notifier = new Notifier(cfg => { cfg.PositionProvider = new WindowPositionProvider( parentWindow: this, corner: Corner.BottomRight, offsetX: 10, offsetY: 10); cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor( notificationLifetime: TimeSpan.FromSeconds(3), maximumNotificationCount: MaximumNotificationCount.FromCount(5)); cfg.Dispatcher = Application.Current.Dispatcher; }); // 此处保留你原有TableDependency初始化逻辑 // _dependency = new SqlTableDependency<Aircraft>(...); // _dependency.OnChanged += _dependency_OnChanged; // _dependency.Start(); }
修改OnChanged事件逻辑
private void _dependency_OnChanged(object sender, TableDependency.SqlClient.Base.EventArgs.RecordChangedEventArgs<Aircraft> e) { if (e.ChangeType != ChangeType.None) { switch (e.ChangeType) { case ChangeType.Update: Console.WriteLine(e.Entity.ACStatus.ToString()); // 显式将通知操作封送到UI线程执行 Application.Current.Dispatcher.Invoke(() => { _notifier.ShowWarning("I AM WORKING"); }); break; } } } private void Notify_Closing(object sender, CancelEventArgs e) { _dependency.Stop(); // 窗口关闭时释放Notifier资源 _notifier.Dispose(); }
内容的提问来源于stack exchange,提问作者Dhafer Ben Arbia
相关产品推荐
相关产品推荐

