Ant*_*ada 4 system.reactive reactiveui
我想在发生错误时显示带有两个按钮的警报对话框。据我所知,这是使用交互属性来做到这一点的方法:
this.ViewModel.ConnectionError.RegisterHandler(interaction =>
{
var retry = await this.DisplayAlert("Connection failed", "Do you want to retry?", "RETRY", "ABORT");
if (retry)
interaction.SetOutput(DevicesViewModel.ErrorRecoveryOption.Retry);
else
interaction.SetOutput(DevicesViewModel.ErrorRecoveryOption.Abort);
});
Run Code Online (Sandbox Code Playgroud)
问题在于异常是在第三方库的线程内引发的。DisplayAlert 必须在主线程中调用。我尝试了以下方法:
this.ViewModel.ConnectionError.RegisterHandler(interaction =>
{
RxApp.MainThreadScheduler.ScheduleAsync(interaction, async (scheduler, i, cancelationToken) =>
{
this.Log().Debug("ScheduleAsync");
var retry = await this.DisplayAlert("Connection failed", "Do you want to retry?", "RETRY", "ABORT");
if (retry)
i.SetOutput(DevicesViewModel.ErrorRecoveryOption.Retry);
else
i.SetOutput(DevicesViewModel.ErrorRecoveryOption.Abort);
return Disposable.Empty;
});
});
Run Code Online (Sandbox Code Playgroud)
我可以在控制台中看到日志消息,但对话框不显示,并且应用程序在 ReactiveUI.dll 内崩溃。我究竟做错了什么?
如果你检查崩溃的细节,我怀疑你会发现它抱怨没有任何东西处理交互。原因是您注册的处理程序是同步的。当然,它会启动异步工作,但是 ReactiveUI 没有提供任何等待该工作完成的方法。
您可以通过查看RegisterHandler您的调用解决的过载来验证这一点。你会发现它是RegisterHandler(Action<InteractionContext<TInput, TOutput>>). 换句话说,“注册一个处理程序,该处理程序获取上下文并同步处理交互。
您想要做的是调用异步RegisterHandler方法之一:
RegisterHandler(Func<InteractionContext<TInput, TOutput>, Task>)RegisterHandler(Func<InteractionContext<TInput, TOutput>, IObservable<Unit>>)有多种方法可以为此编写逻辑。我更喜欢 Rx 作为表达异步的一种方式,所以我会这样写:
this
.ViewModel
.ConnectionError
.RegisterHandler(
context =>
Observable
.Start(
() => Unit.Default,
RxApp.MainThreadScheduler)
.SelectMany(_ => this.DisplayAlert("Connection failed", "Do you want to retry?", "RETRY", "ABORT"))
.Do(result => context.SetOutput(result ? ErrorRecoveryOption.Retry : ErrorRecoveryOption.Abort)));
Run Code Online (Sandbox Code Playgroud)
为了让我们进入正确的线程,这个Observable.Start调用有点麻烦,如果我是你,我会考虑清理它的方法。具体来说,我会考虑在正确的线程上发起交互。也就是说,任何调用Handle(可能是您的虚拟机)都应该在 UI 线程上执行。尽管您有责任在正确的线程上执行命令,Handle但这是相同的。
| 归档时间: |
|
| 查看次数: |
1708 次 |
| 最近记录: |