构造函数中的 WinRT 异步数据加载

本文关键字:数据 加载 异步 WinRT 构造函数 | 更新日期: 2023-09-27 17:55:08

我想在ViewModel的构造函数中加载一些数据,但由于WinRT的异步性质,我被迫使用异步方法。不幸的是,我不能有一个异步构造函数,所以我正在尝试将异步方法用作同步方法。我确信有一种更好的方法可以在应用程序加载时加载数据(异步),但目前我的脑海一片空白。

我要么

正在寻找一种方法来使用我正在走的思路来修复我的应用程序,要么使用更合适的方法永久修复它。

代码非常简单(甚至缺少ViewModel),只是为了演示我面临的问题。

public sealed partial class MainPage : Page
{
    public string Data { get; set; }
    public DataService _dataService { get; set; }
    public MainPage()
    {
        this.InitializeComponent();
        _dataService = new DataService();
        var t = _dataService.GetData();
        Data = t.Result;
    }
    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

}
public class DataService
{
    public async Task<string> GetData()
    {
        //Force async
        await Task.Delay(1);
        return "Hello";
    }
}

亲切问候

构造函数中的 WinRT 异步数据加载

我最近写了一篇关于构造函数中async的博客文章。

简而言之,我更喜欢async工厂方法:

public sealed class MyViewModel : INotifyPropertyChanged
{
  private readonly DataService _service;
  private MyViewModel(DataService service)
  {
    _service = service;
  }
  private async Task InitializeAsync()
  {
    var result = await _service.GetData(); // async initialization
    Data = result; // update data-bound properties with the results
  }
  // Data triggers INotifyPropertyChanged on write
  public string Data { get { ... } set { ... } }
  public static async Task<MyViewModel> CreateAsync()
  {
    var ret = new MyViewModel();
    await ret.InitializeAsync();
    return ret;
  }
}

强制异步方法同步运行通常会导致死锁,所以我不建议这样做。视图模型的特点是,它们通常支持通过INotifyPropertyChanged PropertyChanged事件通知更改,因此无需立即提供所有数据。事实上,如果你的数据不是硬编码的 - 你不应该期望立即看到数据,你很可能希望在加载数据时显示进度指示器。因此。。。

在构造

函数中调用异步初始化方法而不等待结果(因为不能在构造函数中等待),并且在初始化方法中,当所有数据都可用时 - 将其分配给视图绑定到的属性/属性,引发这些属性的 PropertyChanged 事件,并通过更改控制其可见性的视图模型属性来隐藏进度指示器。