Xamarin异步构造函数

问题描述 投票:1回答:2

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

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

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

xamarin xamarin.android xamarin.ios
2个回答
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; }
}

这里,演示是关于将返回的异步值绑定到某些可绑定属性,但是您当然可以没有任何返回值(用于简单数据加载)。


0
投票

这可能太简单了,但是您可以在构造函数中运行异步任务。只需将其包装在一个匿名任务中即可。

public MyConstructor() {
    Task.Run(async () => {
        <Your code>
    }
}

尽管要小心,但如果不小心两次打开页面,可能会遇到资源冲突问题。

我想做的另一件事是使用_isInit标志,该标志指示第一次使用,然后不再使用。

© www.soinside.com 2019 - 2024. All rights reserved.