I have not yet found a definitive solution for those scenarios. I need to load data and it's foreign data asyncronously from db. Data is the ItemSource of a DataGrid ForeignData is the ItemSource of Combos in some DataGridColumns
There are two workflows to implements First workflow: when Refresh button is clicked (i assume it starts in the main thread scope).
RefreshClick() =>
ClearObservableData() =>
LoadDataAsync() =>
LoadForeignDataAsync() =>
UpdateObservableData() =>
UpdateObservableForeignData()
Second workflow (i assume it starts in the background thread scope).
ctor() =>
LoadDataAsync() =>
LoadForeignDataAsync() =>
UpdateObservableData() =>
UpdateObservableForeignData()
Until now, all attemps results in a 80% working workflow but sometimes data is not displayed and it is really difficult (to me) debug, find and understand the problems.
I've tried many different solutions but no one is 100% always working.
This is an example:
From a RelayCommand (Button click):
private void commandReload(object param) //RefreshClick()
{
Task.Run(async () =>
{
await loadAsync();
});
}
Updating Data - test1:
private async Task loadAsync()
{
Data.Clear(); //ClearObservableData()
ForeignData.Clear(); //ClearObservableData()
var data = await service.GetListAsync().ConfigureAwait(false); //LoadDataAsync()
var foreignData = await foreignService.GetListAsync().ConfigureAwait(false); //LoadForeignDataAsync()
if (data != null)
{
foreach (var item in data)
{
Data.Add(item);
}
}
if (foreignData != null)
{
foreach (var foreignItem in foreignData )
{
ForeignData.Add(foreignItem );
}
}
}
Updating Data - test2:
private async Task loadAsync()
{
Data.Clear(); //ClearObservableData()
ForeignData.Clear(); //ClearObservableData()
var data = await service.GetListAsync().ConfigureAwait(false); //LoadDataAsync()
var foreignData = await foreignService.GetListAsync().ConfigureAwait(false); //LoadForeignDataAsync()
var context = SynchronizationContext.Current;
context.Send(x =>
{
Data.Clear();
foreach (var item in data)
{
Data.Add(item);
}
}, null);
//......
}
Updating Data - test3:
private async Task loadAsync()
{
Data.Clear(); //ClearObservableData()
ForeignData.Clear(); //ClearObservableData()
var data = await service.GetListAsync().ConfigureAwait(false); //LoadDataAsync()
var foreignData = await foreignService.GetListAsync().ConfigureAwait(false); //LoadForeignDataAsync()
Application.Current.Dispatcher.Invoke(() =>
{
foreach (var item in data)
{
Data.Add(item);
}
});
//......
}
Code here is simplified for many obviously reasons.
service.GetListAsync() is based on EFCore and is more or less something like this:
public async Task<IEnumerable<MyItem>> GetListAsync()
{
var set = Set<MyItem>().AsQueryable();
return set.AsNoTrackingWithIdentityResolution();
}