ReactiveUI - 如何管理 ReactiveCommand 异常?
我有一个简单的用户控件,其中包含 ViewModel 和 ReactiveCommand CheckForUpdates
,它在后台运行并可能会抛出异常。该命令在 ViewModel 的 WhenActivated 方法中显式执行。我想要实现的就是捕获异常并将其记录在 ViewModel 中,并向用户另外显示消息框。问题是,当我添加 Catch
时,ThrownExceptions
不会返回任何内容,并且不会显示 MessageBox。当我删除 Catch
时,应用程序崩溃...我不知道如何正确执行此操作?
public partial class SettingsDialog : SettingsDialogBase, IDialog
{
public SettingsDialog()
{
InitializeComponent();
this.WhenActivated((CompositeDisposable d) =>
{
ViewModel
.CheckForUpdates
.ThrownExceptions
.Subscribe(ex =>
{
MessageBoxHelper.ShowError(ex); // doesn't fire when `Catch` is present in ViewModel
})
.DisposeWith(d);
});
}
}
ViewModel:
public ReactiveCommand<Unit, ApplicationUpdateInfo> CheckForUpdates { get; set; }
public SettingsDialogViewModel(IApplicationUpdateService updateService)
{
CheckForUpdates = ReactiveCommand.CreateFromTask(async () =>
{
return await CheckForUpdatesAsync();
});
this.WhenActivated((CompositeDisposable d) =>
{
CheckForUpdates
.Execute()
.Catch(Observable.Return(new ApplicationUpdateInfo())) // crashes the app if removed
.Subscribe()
.DisposeWith(d);
});
}
private async Task<ApplicationUpdateInfo> CheckForUpdatesAsync()
{
throw new Exception("Error");
}
I have simple user control with a ViewModel and a ReactiveCommand CheckForUpdates
which runs in background and may throw. This command is explicitly executed in ViewModel's WhenActivated
method. All I want to achieve is to catch the exception and log it in ViewModel, and additionally show Message Box to the user. The problem is, when I add Catch
, then ThrownExceptions
doesn't return anything and the MessageBox is not shown. When I remove Catch
, the application crashes... I don't know how to do this properly??
public partial class SettingsDialog : SettingsDialogBase, IDialog
{
public SettingsDialog()
{
InitializeComponent();
this.WhenActivated((CompositeDisposable d) =>
{
ViewModel
.CheckForUpdates
.ThrownExceptions
.Subscribe(ex =>
{
MessageBoxHelper.ShowError(ex); // doesn't fire when `Catch` is present in ViewModel
})
.DisposeWith(d);
});
}
}
ViewModel:
public ReactiveCommand<Unit, ApplicationUpdateInfo> CheckForUpdates { get; set; }
public SettingsDialogViewModel(IApplicationUpdateService updateService)
{
CheckForUpdates = ReactiveCommand.CreateFromTask(async () =>
{
return await CheckForUpdatesAsync();
});
this.WhenActivated((CompositeDisposable d) =>
{
CheckForUpdates
.Execute()
.Catch(Observable.Return(new ApplicationUpdateInfo())) // crashes the app if removed
.Subscribe()
.DisposeWith(d);
});
}
private async Task<ApplicationUpdateInfo> CheckForUpdatesAsync()
{
throw new Exception("Error");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该在抛出异常之前订阅
ThrownExceptions
。您通常在视图模型的构造函数中执行此操作:
如果您想在视图中订阅 ThrownExceptions,您需要在视图模型抛出之前执行此操作,例如:
You should subscribe to
ThrownExceptions
before the exception is thrown.You typically do this in the constructor of the view model:
If you want to subscribe to
ThrownExceptions
in the view, you need to do it before the view model throws, e.g.: