MVVMCross ViewModel构建失败通知 [英] MVVMCross ViewModel construction failure notifications

查看:78
本文介绍了MVVMCross ViewModel构建失败通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经注意到移动应用程序中有几次用户报告应用程序挂起或在视图之间变得无响应/在视图之间切换时罕见的崩溃.我们已经将这些情况追溯到视图模型构造函数抛出未捕获的异常的时候.

We've noticed a couple of times in our mobile applications that users have reported the application hanging or seeming to become unresponsive between views / rare crashes when switching between views. We've tracked down these cases to when our view model constructors throw uncaught exceptions.

我们想采用一个解决方案,以便如果由于某种原因无法构建视图模型,那么我们可以通知用户并提供一些消息,当通过支持进行登录时,这对我们很有用.

We want to put a solution in place so that if a view model fails to construct for some reason then we can notify the user and provide some message that will be useful to us when it's logged through support.

我一直在研究这样做,但是还没有找到一种可靠的方法来实现这一目标.

I've been taking a look at doing this but haven't found a reliable way to achieve this.

我们尝试的第一件事是在IMvxViewModelLocator级别.我们已经有IMvxViewModelLocator的自定义实现,因此我们已经对其进行了修改.我们允许抛出所有异常,然后有每个平台都实现的IErrorHandler接口.然后,我们将其称为尝试显示对话框.事实证明这是不可靠的,并且对话框不会始终显示.类似于以下内容:(请注意-这里ResolveViewModel将始终返回true或throw)

The first thing we tried was at the IMvxViewModelLocator level. We already have a custom implementation of IMvxViewModelLocator so we've modified this. We allow all exceptions to be thrown and then we have an IErrorHandler interface which each platform implements. We then call this to attempt to show a dialog. This has proved to be unreliable and the dialog does not always display. Something along the lines of: (note - here ResolveViewModel will always return true or throw)

    public override bool TryLoad(Type viewModelType, IMvxBundle parameterValues, IMvxBundle savedState, out IMvxViewModel viewModel)
    {
        try
        {
            return ResolveViewModel(viewModelType, parameterValues, savedState, out viewModel);
        }
        catch (Exception exception)
        {
            _errorHandler.HandleViewModelConstructionException(viewModelType, exception);
            viewModel = null;
            return false;
        }
    }

我们理想地要做的是拦截构造视图模型的所有失败,然后重新请求ErrorViewModel.我们尝试了两种方法:

What we would ideally like to do is intercept any failure to construct a view model and then re-request an ErrorViewModel. We've tried to do this 2 ways:

1) 我们已经尝试为每个平台定义一个自定义IMvxViewDispatcher,并且尝试拦截以下错误,但是如果在构造函数中抛出异常,我们将永远不会退缩:

1) We've tried defining a custom IMvxViewDispatcher for each platform and we're trying to intercept failures as below but if an exception in the constructor is thrown we never get back this far:

public class TouchDispatcher : MvxTouchUIThreadDispatcher, IMvxViewDispatcher
{
    private readonly IMvxTouchViewPresenter _presenter;

    public TouchDispatcher(IMvxTouchViewPresenter presenter)
    {
        _presenter = presenter;
    }

    public bool ShowViewModel(MvxViewModelRequest request)
    {
        Action action = () =>
            {
                _presenter.Show(request);
            };
        try
        {
            bool success = RequestMainThreadAction(action);
            return !success ? HandleError() : success;
        }
        catch (Exception)
        {
            return HandleError();
        }
    }
    // Other bits
}

2) 我们认为在主持人级别上我们可能会取得更大的成功.我们针对每个平台修改了ViewPresenter,并覆盖了void Show(MvxViewModelRequest request).事实证明,这也不成功,因为异常不会传播到这么远.

2) We thought we might have more success at the presenter level. We modified our ViewPresenter for each platform and we have overridden void Show(MvxViewModelRequest request). This has not proved to be successful either as exceptions don't propagate back this far.

这让我觉得也许我们最好在IMvxViewModelLocator级别上再次尝试.

This leaves me thinking that maybe we are better attempting this at the IMvxViewModelLocator level again.

有没有人找到一种方法来可靠地拦截构造视图模型的失败,然后理想地重新请求其他视图模型/向用户显示一些对话框?

Has anyone found a way to reliably intercept failures to construct view models and then ideally re-request a different view model / present some dialog to the user?

推荐答案

看来您已经确定问题的核心是何时:视图模型构造函数引发未捕获的异常."

It seems you've identified that the core of the problem is when: "view model constructors throw uncaught exceptions."

这会有些问题,因为通常在诸如ViewDidLoadOnCreateNavigatedTo之类的View生命周期覆盖过程中构造ViewModel,这通常是在Presenter完成请求演示之后.

This is going to be slightly problematic as the ViewModel's are generally constructed during View lifecycle overrides like ViewDidLoad, OnCreate or NavigatedTo - which is generally after the Presenter has finished requesting presentation.

在自定义IMvxViewModelLocator中,您已经找到了一个很容易识别ViewModel构造失败的地方-其他也可能是IMvxViewModelLoader.这可能是最容易捕获错误并触发错误处理的地方-然后,您可以在那里握住IMvxViewDispatcher(或演示者)以更改显示.但是,您仍然需要确保您的视图可以处理null创建的ViewModel-因为ViewDidLoad等调用仍需要完成.

As you've already found an easy place to identify when ViewModel construction has failed is in a custom IMvxViewModelLocator - others likeIMvxViewModelLoader are also possible. This is probably the easiest place to catch the error and to trigger the error handling - you can then get hold of the IMvxViewDispatcher (or presenter) there in order to change the display. However, you will still need to make sure your Views can handle null created ViewModels - as the ViewDidLoad, etc calls will still need to complete.

这篇关于MVVMCross ViewModel构建失败通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆