ReactiveUI - 在交互处理程序中使用调度程序

时间:2016-12-13 08:18:31

标签: system.reactive reactiveui

我想在发生错误时显示带有两个按钮的警告对话框。 据我所知,这是使用Interaction属性的方法:

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);
});

问题是异常是在第三方库中的线程内引发的。必须在主线程中调用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;
    });
});

我可以在控制台中看到日志消息,但对话框没有显示,应用程序在ReactiveUI.dll内崩溃。 我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果您检查崩溃的详细信息,我怀疑您会发现它抱怨没有任何处理交互。原因是您的注册处理程序是同步的。当然,它会启动异步工作,但是您没有给ReactiveUI任何等待该工作完成的方法。

您可以通过查看通过呼叫解决的RegisterHandler(Action<InteractionContext<TInput, TOutput>>)超载来验证这一点。你会发现它RegisterHandler。换句话说,&#34;注册一个处理器,它接受上下文并同步处理交互。

您要做的是调用异步RegisterHandler(Func<InteractionContext<TInput, TOutput>, Task>)方法之一:

  • RegisterHandler(Func<InteractionContext<TInput, TOutput>, IObservable<Unit>>)
  • 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)));

为此编写逻辑有多种方法。我倾向于选择Rx作为表达异步的手段,所以我这样写:

Observable.Start

Handle电话会让我们找到正确的话题,而且如果我是你,我还会考虑如何清理它。具体来说,我看看在正确的线程上发起交互。也就是说,无论调用Handle(可能是您的VM)都应该在UI线程上执行此操作。尽管您有责任在正确的线程上执行命令,{{1}}也是如此。