Avalonia修改Greeting属性触发通知时应用崩溃如何解决
问题根因
你的应用崩溃核心有两个触发点:
- ReactiveUI的
WhenAnyValue方法会在订阅时立刻推送当前属性的初始值作为第一个回调参数,你在ViewModel构造函数中订阅Greeting后,会立刻触发ShowNotification调用,此时窗口还处于构造过程中,WindowNotificationManager依赖的窗口句柄还未完成初始化,直接调用Show方法就会抛出异常。 - 未指定订阅回调的调度线程,若回调触发时不在UI线程,操作UI相关的通知弹窗也会导致崩溃。
解决方法
1. 修正属性订阅逻辑
修改ViewModel中Greeting的订阅代码,跳过初始值推送、指定UI线程调度即可解决崩溃问题:
// 原代码 // this.WhenAnyValue(x => x.Greeting).Subscribe(x=>ShowNotification(x)); // 修改为 this.WhenAnyValue(x => x.Greeting) // 跳过初始值的第一次自动推送,仅在手动修改属性时触发通知 .Skip(1) // 强制回调在UI线程执行,避免跨线程操作UI异常 .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x=>ShowNotification(x));
2. 可选优化项
- 调整通知自动关闭时长:你当前设置的
TimeSpan.FromSeconds(0)表示通知永久不自动关闭,若需要自动关闭可调整为合理值,示例如下:
Notification = new Avalonia.Controls.Notifications.Notification( "TestNotification", s, Avalonia.Controls.Notifications.NotificationType.Information, TimeSpan.FromSeconds(3) // 3秒后自动关闭 );
- 优化随机数生成逻辑:不要每次点击按钮都重新实例化
Random,将其设为类全局字段避免短时间内生成重复随机值:
// 在ViewModel类中添加私有字段 private Random _rand = new Random(); public void ClickEvent(object sender, Avalonia.Interactivity.RoutedEventArgs e) { int x = _rand.Next(0, 3); Greeting = stringArray[x]; }
修改完成后点击按钮修改Greeting属性就可以正常弹出通知,不会出现崩溃问题。
内容的提问来源于stack exchange,提问作者pzogr
相关产品推荐
相关产品推荐

