使用 Xamarin 表单导航页面时出现死锁

Deadlocking when navigating pages with Xamarin forms

我使用 Xamarin Forms 编写的移动应用程序出现了一些奇怪的行为,前提很简单:

因为我使用的是 mvvm,所以我无法连接到任何页面事件 (appearing/disappearing/etc。)所以我只能开始从构造函数中检索数据(我知道这是个坏主意)。

这就是(我认为)问题所在:

导航器(运行在 UI 线程上)异步解析视图和视图模型 viewmodel 无法从构造函数异步加载数据,因此它会阻塞 UI 线程,直到加载完成。

只要您的网络连接足够快,您甚至可能不会注意到它,但当它确实花费太长时间时,系统似乎认为它处于死锁状态并终止。

所以我尝试使用

来解决这个问题
Task.Factory.StartNew(() => { GetData(); });

在构造函数中,这在大约 80% 的时间内都有效,但正如我发现的那样,启动一个新任务并不能保证一个新线程。

因此,数据检索任务偶尔会 运行 在 UI 线程上阻塞它,加载时间稍长会导致崩溃。

是否有使用 mvvm 进行异步数据加载的简洁方法?

好的,所以我找到了问题。这确实是网络代码阻塞应用程序的问题,但由于我自己编写了这个项目的 99%,我假设所有这些都使用了我的中央网络管理器。

我错了。在代码深处的某个地方,在一个基础 类 中,有一些跟踪和加载本地化的逻辑。 它的工作原理有点像这样:

  • 解析页面
  • 解析视图模型
  • 检查视图模型翻译
  • 我记忆中有必要的翻译吗?
  • 没有?我的本地数据库中有它们吗?
  • 又不是?尝试从本地化服务器加载它们
  • 将翻译保存在数据库和内存中并将它们添加到视图模型中
  • 将视图模型绑定到视图。

由于我们使用的是 MVVM,因此要及时加载翻译并在其余部分加载完成之前显示它们是一项挑战(我们找不到一种方法来提醒 UI翻译数据库发生了变化)。

所以原作者选择了同步加载翻译,正如您此时可能已经猜到的那样,阻塞了 UI 线程,直到它完成或花费太长时间而崩溃。

这基本上意味着我花了两天的大部分时间重写了整个视图解析逻辑以异步工作并做了一些翻译预取(必要时)。