对于我的应用程序,我需要异步获取一些数据并对每个页面进行一些初始化。不幸的是,构造函数不允许我进行异步调用。我遵循了this article并将所有代码放入OnAppearing
方法中。但是,此后我遇到了多个问题,因为每个平台对事件的处理都略有不同。例如,我有一些页面可以拍照,在iOS上,每次关闭相机后OnAppearing
都会再次调用,而Android则没有。对于我的需求来说,这似乎不是一种可靠的方法,here也对此进行了描述:
对
OnDisappearing
和OnAppearing
替代的调用不能被视为保证页面导航的指示。例如,在iOS上,当应用程序终止时,将在活动页面上调用OnDisappearing
覆盖。
我正在寻找可以执行自己的初始化的方法/方式。构造函数将是完美的选择,但我无法在其中异步执行任何操作。请不要为我提供任何解决方法,我正在寻找一种“推荐”方式的解决方案,或者有很多经验的人可以告诉我他们在做什么。 (我也不想使用.Wait()或.Result,因为它会锁定我的应用程序)
答案 0 :(得分:0)
您可以使用Stephen Cleary出色的NotifyTaskCompletion类。
在Microsoft出色的Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding中,您可以了解更多这些情况下的工作原理以及做什么/不做什么。该主题的重点是:
让我们逐步了解核心方法 NotifyTaskCompletion.WatchTaskAsync。该方法需要完成一项任务 代表异步操作,并(异步)等待 完成它。注意,await不使用 ConfigureAwait(false);我想回到UI上下文之前 引发PropertyChanged通知。此方法违反了 此处的通用编码准则:它具有一个空的常规catch子句。在 不过,这正是我想要的。我不想 将异常直接传播回主UI循环;我想要 捕获所有异常并设置属性,以便进行错误处理 通过数据绑定完成。任务完成后,类型会提高 所有适当属性的PropertyChanged通知。
示例用法:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
这里,演示是关于将返回的异步值绑定到某些可绑定属性,但是您当然可以没有任何返回值(用于简单数据加载)。
答案 1 :(得分:-1)
这可能太简单了,但是您可以在构造函数中运行异步任务。只需将其包装在一个匿名任务中即可。
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
执行此操作时请务必小心,因为如果您不小心打开两次页面会遇到资源冲突问题。
我想做的另一件事是使用_isInit标志,该标志指示第一次使用,然后不再使用。