Xamarin异步构造函数

时间:2020-05-26 19:56:55

标签: xamarin xamarin.android xamarin.ios

对于我的应用程序,我需要异步获取一些数据并对每个页面进行一些初始化。不幸的是,构造函数不允许我进行异步调用。我遵循了this article并将所有代码放入OnAppearing方法中。但是,此后我遇到了多个问题,因为每个平台对事件的处理都略有不同。例如,我有一些页面可以拍照,在iOS上,每次关闭相机后OnAppearing都会再次调用,而Android则没有。对于我的需求来说,这似乎不是一种可靠的方法,here也对此进行了描述:

OnDisappearingOnAppearing替代的调用不能被视为保证页面导航的指示。例如,在iOS上,当应用程序终止时,将在活动页面上调用OnDisappearing覆盖。

我正在寻找可以执行自己的初始化的方法/方式。构造函数将是完美的选择,但我无法在其中异步执行任何操作。请不要为我提供任何解决方法,我正在寻找一种“推荐”方式的解决方案,或者有很多经验的人可以告诉我他们在做什么。 (我也不想使用.Wait()或.Result,因为它会锁定我的应用程序)

2 个答案:

答案 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标志,该标志指示第一次使用,然后不再使用。