简体   繁体   中英

Deadlocking when navigating pages with Xamarin forms

I've been getting a bit of strange behavior from the mobile app I'm writing using Xamarin Forms, the premise is simple:

  • Navigate to a new page (this happens asynchronously)
  • Retrieve some data (asynchronously as well)
  • Bind data to view

Because I'm using mvvm I can't hook into any of the page events (appearing/disappearing/etc.) so I can only start retrieving data from the constructor (bad idea, I know).

That's where (I think) the issue lies:

the navigator (running on the UI Thread) asynchronously resolves the view and viewmodel the viewmodel can't load the data asynchronously from the constructor so it blocks the UI Thread untill the loading is done.

And as long as your network connection is fast enough you might not even notice it, but when it does take too long the system appears to think it's in a deadlock and terminates.

So I've tried to solve this by using

Task.Factory.StartNew(() => { GetData(); });

in the constructor and this works about 80% of the time but, as I've discovered, starting a new task does not guarantee a new Thread.

So once in a while the data retrieval task will run on the UI Thread, blocking it and take just slightly too long to load resulting in a crash.

Is there a clean way of async data loading with mvvm?

ok, so I found the problem. It was indeed a problem with network code blocking the application but since I wrote 99% of this project myself I assumed that all of it used my central network manager.

I was wrong. Somewhere deep in the bowels of the code, in one of the base classes, there is a bit of logic that tracks and loads localizations. It works a bit like this:

  • resolve page
  • resolve viewmodel
  • check viewmodel translations
  • do i have the necessary translations in memory?
  • no? Do i have them in my local db?
  • again no? Attempt to load them from a localization server
  • save translations in db and memory and add them to the viewmodel
  • bind viewmodel to view.

Since we're using MVVM it was a challenge to get the translations to load in time and show them before the rest was done loading (we couldn't find a way to alert the UI that there had been a change in the translations db).

So the original author had chosen to load the translations synchronously which, as you might've guessed at this point, blocked the UI thread untill it either finished or took too long and crashed.

This basically means that I have spent the better part of two days rewriting the entire view-resolving logic to work asynchronously and do a bit of pre-fetching of the translations (where necessary).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM