I'm rewriting some parts of our MVVM framework to make use of the async/await features, consider the following VM code:
private async Task LoadDossier(int ID)
{
//VM INotifyProperty
Dossiers = new ObservableCollection<Dossier>(await BubManager.GetAllBubDossiersForEmployeeByDossierIdAsync(ID).ConfigureAwait(false));
//VM INotifyProperty
SelectedDossier = Dossiers.First(x => x.Id == ID);
//VM INotifyProperty
DossierEmployer = await EmployerManager.GetEmployerByIdAsync(SelectedDossier.EmployerId).ConfigureAwait(false);
//VM INotifyProperty
DossierEmployee = await EmployeeManager.GetEmployeeByIdAsync(SelectedDossier.EmployeeId).ConfigureAwait(false);
//All VM INotifyProperties
if (SelectedDossier != null && DossierEmployer != null)
{
RszNr = DossierEmployer.RszNr;
FundsNr = DossierEmployer.FundsNr;
RrNr = DossierEmployee.RrNr;
}
RefreshGlobalCommanding();
}
As I'm using strict MVVM there is not a single property here that needs the UI thread, therefore I'm using ConfigureAwait(false) everywhere. I am aware that this is not possible when adding/removing from an ObservableCollection, but this is not the case here.
ConfigureAwait(false) doesn't help readability IMOEDIT
Following the discussion with Stephen I came to the conclusion that It's basically the same thing.
ConfigureAwait(false), you are telling WPF that the callback doesn't have to be on the UI thread. When setting an INotifyProperty, WPF makes sure the UI thread gets the notification.Both cases make WPF do the UI thread marshalling at some point. However, I compared the performance of the two and there is a significant difference. I executed a loop 1000 times where an object gets bound to a view and then is set to null again, here are the results in milliseconds:
One await call with a task delay of 10ms
ConfigureAwait(false)Three await calls with a task delay of 10ms
ConfigureAwait(false)This benchmark is far from perfect, but it seems marshalling back properties to the UI thread is less costly than obliging everything after an await call to run on the same thread. This needs more testing to give a definitive answer for all scenario's however.
I'm just putting this here to document that there are differences between the two. My advice would be to not use ConfigureAwait in this scenario because it raises the chance for exceptions when altering your code, is less readable and colleagues may not understand the point and get a false sense of security by using this.
Is this code a good practice?
Personally, I choose to treat all data-bound properties as though they had UI-affinity.
One reason is that different MVVM frameworks have different capabilities in this regard; it's true that WPF will handle this for you (for simple properties), but others will not.
If it is, then why can't you make this the default behavior?
When async was in CTP, there were tons of discussions regarding this default behavior of await. There are pros and cons each way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With