使用Xamarin表单导航页面时发生死锁

时间:2016-02-19 14:07:36

标签: c# asynchronous mvvm deadlock xamarin-forms

我从使用Xamarin Forms的移动应用程序中得到了一些奇怪的行为,前提很简单:

  • 导航到新页面(这是异步发生的)
  • 检索一些数据(也是异步的)
  • 绑定数据以查看

因为我使用mvvm,我无法挂接到任何页面事件(出现/消失/等),所以我只能从构造函数开始检索数据(我知道这是个坏主意)。

问题出在哪里(我认为):

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

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

所以我试图通过

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

在构造函数中,大约80%的时间都可以工作,但是,正如我发现的那样,启动新任务并不能保证新的线程。

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

mvvm是否有一种干净的异步数据加载方式?

1 个答案:

答案 0 :(得分:0)

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

我错了。在某个深层的代码中,在其中一个基类中,有一些跟踪和加载本地化的逻辑。 它有点像这样:

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

由于我们正在使用MVVM,因此要及时加载翻译并在其余部分加载完成之前显示它们是一项挑战(我们无法找到一种方法来提醒用户界面已经发生了变化翻译db)。

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

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