WinRT async data load in constructor

后端 未结 2 1933
暗喜
暗喜 2020-12-31 18:53

I want to load some data in the constructor of a ViewModel but due to WinRT\'s async nature I am forced to use async methods. Unfortunately I cannot have an async constructo

相关标签:
2条回答
  • 2020-12-31 19:10

    Forcing async methods to run synchronously usually leads to deadlocks, so I would not recommend that. The thing with view models is that they usually support change notifications through INotifyPropertyChanged PropertyChanged event, so there is no need to have all data available immediately. In fact if your data isn't hard-coded - you shouldn't expect to see the data immediately and you would most likely want to show a progress indicator while the data is loading. Thus...

    In your constructor call an async initialization method without awaiting the result (since you can't await in a constructor) and in the initialization method when all data is available - assign it to property/properties that your view binds to, raise PropertyChanged event for these properties and hide the progress indicator by changing the view model property that controls its visibility.

    0 讨论(0)
  • 2020-12-31 19:13

    I wrote a recent blog post about async in constructors.

    In short, I prefer an async factory method:

    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;
      }
    }
    
    0 讨论(0)
提交回复
热议问题