Ian Vink
Ian Vink

Reputation: 68750

Xamarin.Forms DataBinding Update while other tasks running

In my UI I have to get three sets of data from three services, then show the three sets of data on the screen. I want the the UI to update as soon as the data from a service comes back, but the UI doesn't update until all the three services comes back?

simplified

public async Task Refresh()
{
    var a = await GetA();
    observableCollectionA.AddRange(a); 
    RaisePropertyChanged(nameof(observableCollectionA ));

    var b = await GetB();
    observableCollectionB.AddRange(b); 
    RaisePropertyChanged(nameof(observableCollectionB ));

    var c = await GetC();
    observableCollectionC.AddRange(c); 
    RaisePropertyChanged(nameof(observableCollectionC ));

    //Not until they all come back do I see the changes on the screen
}

Upvotes: 2

Views: 101

Answers (3)

LeRoy
LeRoy

Reputation: 4436

You can also use ConfigureAwait

GetA().ConfigureAwait(false);
GetB().ConfigureAwait(false);
GetC().ConfigureAwait(false);

Upvotes: 0

Diego Rafael Souza
Diego Rafael Souza

Reputation: 5313

It seems to be a common need on your project. I guess you can get same results with something a bit more reusable...

Maybe you should make a try with this:

public async Task Refresh()
{
    await Task.WhenAll(
        AddAndNotify(new ObservableCollection<object>(), GetA(), "CollectionA"),
        AddAndNotify(new ObservableCollection<object>(), GetB(), "CollectionB"),
        AddAndNotify(new ObservableCollection<object>(), GetC(), "CollectionC")
    );

    // Then, do something
}

public async Task AddAndNotify<T>(ObservableCollection<T> collection, Task<IEnumerable<object>> getElementsService, string propertyNameToNotifyChanged)
{
    collection.AddRange(await Task.Run(() => getElementsService));
    RaisePropertyChanged(propertyNameToNotifyChanged);
}

In this example, I have the "Get" methods like this:

public async Task<IEnumerable<object>> GetA()
{
    return new List<object>( new [] { (object)null });
}

Thus the three calls will be made "in parallel".

I hope it helps.

Upvotes: 1

Ian Vink
Ian Vink

Reputation: 68750

I found that by moving each into its own function with its own await, that made it work:

await GetAAndUpdateUI();
await GetBAndUpdateUI();
await GetCAndUpdateUI();

Upvotes: 0

Related Questions