CoreDispatcher.HasThreadAccess “breaking change”

♀尐吖头ヾ 提交于 2019-12-25 01:58:57

问题


I am taking over an application developed with MvvmCross.vNext.
While trying to update it with MvvmCross.V3, I found the following breaking change: in the constructor of the MainViewModel, we show the LoginViewModel (ShowViewModel()). It worked fine in vNext.
But with V3, the LoginView doesn't show.
After a long search, I found out that the following code, added in MvxStoreMainThreadDispatcher.RequestMainThreadAction :

        if (_uiDispatcher.HasThreadAccess)
        {
            action();
            return true;
        }

was responsible for my troubles.
If I comment it out, my application works as previously, but I guess this code is there for some reasons...
Do you have any suggestions ?
Can I force the previous behavior without changing MvvmCross source code?
Should I refactor the code to handle the LoginView differently ?
Thanks in advance for your comments.
Philippe


回答1:


While trying to update it with MvvmCross.V3, I found the following breaking change: in the constructor of the MainViewModel, we show the LoginViewModel (ShowViewModel()). It worked fine in vNext.

I think your constructor navigation would have broken on several platforms in any MvvmCross version. To be honest, I think you were lucky it worked before.

The problem is that ViewModels are constructed (or located) during View events such as ViewDidLoad, OnNavigatedTo, and OnCreate - and these events are normally called during 'page transitions'

To work around this you will need to move your login navigation out of the constructor.

How you do this depends on your app

  • if you do need the Home->Login backstack, then you can trigger off some async or time delay or you can trigger off some other View event such as something like ViewDidAppear

  • if you don't need that backstack then the way I normally implement this sort of thing is to use a custom IMvxAppStart - something like:

    public class AppStart
        : MvxNavigatingObject
        , IMvxAppStart      
    {
        public void Start(object hint = null)
        {
            var authService = Mvx.Resolve<IMySerice>();
            if (authService.IsLoggedIn)
            {
                ShowViewModel<HomeViewModel>();
            }
            else
            {
                ShowViewModel<LoginViewModel>();
            }
        }
    }
    

    (you can see another example in https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CirriousConference/Cirrious.Conference.Core/ApplicationObjects/AppStart.cs)

    This can be registered in App.cs startup using:

    RegisterAppStart(new AppStart());
    


来源:https://stackoverflow.com/questions/16100110/coredispatcher-hasthreadaccess-breaking-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!