0

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();
}
Noschema
  • 31
  • 6
  • Why `AsQueryable`? What is the type of `Data` and `ForeignData`? Are they UI elements or data bound to UI elements? – Paulo Morgado Jul 28 '22 at 10:29
  • Think type as T class. It could be everything. I missed code where i map entities to INotifyPropertyChange objects. – Noschema Jul 28 '22 at 13:04
  • Your `Data` and `ForeignData` need to be ObservableCollection or something Observable, or else the `Add` wont raise a Notification, regardless of if the contained Entities implement `INotifyPropertyChanged`. Not sure if they are, but that could be one issue why you dont see the update. – Ginger Ninja Jul 28 '22 at 16:13
  • The question is about async await behavior. In the ViewModel all collections used to display data are ObservableCollection. Objects added to those collections inherits from INotifyPropertyChange. Syncronous code works well. – Noschema Jul 29 '22 at 06:10
  • You should not be using ConfigureAwait(false); – Andy Jul 30 '22 at 17:50

0 Answers0