Assuming you know about ObservableCollection and the consequences of using async void (see my comments down below), I'd recommend one of these ways:
The easier way is to simply call a InitializeAsync() method to start loading in the constructor:
class MyViewModel
{
public MyViewModel()
{
InitializeAsync();
}
//warning: async void!
public async void InitializeAsync()
{
Records = await _database.LoadData();
}
}
Or you could adapt the _database Service to do the lazy loading (I recommend this method, as it keeps the ViewModel clean):
class MyViewModel
{
public MyViewModel()
{
Records = _database.LoadData();
}
}
class Database
{
private ObservableCollection<Record> _data = new ObservableCollection<Record>();
public ObservableCollection<Record> LoadData()
{
EnsureLoaded();
return _data;
}
private bool _isLoaded = false;
private async void EnsureLoaded()
{
lock (this)
{
if (_isLoaded)
return;
_isLoaded = true;
}
//do the actual loading here
var myResultList = await DoLoadingAsync();
foreach (myResultList as item)
{
_data.Add(item);
}
}
}
Notes about async void:
You can use void (instead of Task) as a return type of an asynchronous method. This will result in a "fire-and-forget" action:
public void DoStuff()
{
FireAndForgetAsync();
}
private async void FireAndForgetAsync()
{
await Task.Delay(1000);
throw new Exception(); //will be swallowed
}
As you are returning void, you can not await FireAndForgetAsync. You will not be able to know when the method finishes, and any exception raised inside the async void method will be swallowed.
Notes about ObservableCollection:
This type of List raises an event once you add / remove / replace items. You can use this events to fill your view without having to reload the list as a whole each time it changes.
If you implement this correctly you can show the user each item as soon as it finished loading, instead having him to wait until everything is loaded fully.