Async void when overridden

I am aware of the flaws of methods async void

, but not entirely sure about the best way to overcome the problem when overriding methods.

Let's say I have the following code:

protected override async void PageRefreshed()
{
    BoundDataField = await LoadDataFromWeb();
}

      

I know this is very bad, but what's the best solution for this?

  • LoadDataFromWeb().ContinueWith(r => BoundDateField = r.Result);

  • Task.Run(async ()=> await LoadDataFromWeb())).Wait;

  • LoadDataFromWeb().Wait

  • BoundDataField = LoadDataFromWeb.Result

I'm pretty sure 3 and 4 are real no nos as they will block the UI thread. Is there any other solution I missed?

+3


source to share


1 answer


I'm sure 3 and 4 are real no nos as they will block the UI thread.

Not just blocking, but quite possibly blocking .

Is there any other solution I missed?

What you are trying to do is get the value of the data-bound property asynchronously. I'll cover this in detail in the MSDN article on Asynchronous Data Binding .

First, the central thing to acknowledge is that it is not possible, as written. There are two conflicting requirements:

  • The computer should immediately display something.
  • You need to display data and it will take time.

So, you need to compromise:

  • The computer receives some placeholder data or a counter or something that needs to be displayed right away.
  • You update the display with real data when it arrives.


Put this way, the code is more simple:

protected override async void PageRefreshed()
{
  BoundDataField = "placeholder"; // synchronous immediate placeholder data
  BoundDataField = await LoadDataFromWeb(); // asynchronous update
}

      

or

protected override async void PageRefreshed()
{
  // Synchronously show spinner
  IsBusy = true;

  // Asynchronously load data and then hide spinner
  BoundDataField = await LoadDataFromWeb();
  IsBusy = false;
}

      

Note that this simple solution does not handle errors well and also does not handle multiple "updates", possibly updating this field out of order. A more advanced approach is to use my NotifyTask<T>

type
from the Nito.Mvvm.Async

NuGet package :

protected override void PageRefreshed()
{
  BoundDataField = NotifyTask<TData>.Create(LoadDataFromWeb());
}

      

This approach requires updating the data binding code; BoundDataField.Result

is now the actual data value BoundDataField.IsNotCompleted

, a BoundDataField.IsFaulted

, and other properties can be used to make your data binding respond to incomplete or corrupted states.

+6


source







All Articles