Quantcast
Viewing latest article 40
Browse Latest Browse All 76418

Always use Task.Run() for the best User Experience.

I'm using this rather abrasive statement as a sort of hypotheses. Please do not take offense to this title. I merely used this as a means of grabbing attention and starting a discussion.

This discussion is furthered from the following thread:
https://forums.xamarin.com/discussion/139992/calling-async-methods-from-main-thread-is-a-bad-idea?

I will now try to explain the case.

Consider the following code taken directly from the thread in the link above:

protected override async void OnResume()
{
    //show preloader

    var result = await SlowAsync(); //blocks UI
    //---versus---
    var task = SlowAsync();
    var result = await task; //also blocks UI
    //---versus---
    var result = await Task.Run(async ()=> await SlowAsync()); //does not block UI

    //update UI, hide preloader
}

public async Task<bool> SlowAsync()
{
    FindPrimeNumber(100000); //or whatever sync, usually not that CPU-heavy, but still blocking the UI for some precious milliseconds (some conditions, sorting some lists, anything)

    await Task.Delay(10); //or whatever async, some server fetch, this is not blocking the UI, the main thread is released until it is finished .. unless it also contains some synchronous code

    return true;
}

The OnResume() method in this code should give a fair example of the problem:
async methods will block the main thread until the point where a new thread is started.

More descriptively:
When a slow, async method is called from a lifecycle method or a command, it will run entirely on the main thread, even if it is marked as async. On Android, this causes the entire application to freeze. To the detriment of the user experience.

You can force a release of the main thread by starting all these methods with await Task.Run(). Animations will play normally on Android and the application wont freeze.

In the application I'm working on with my team I implemented this and it improved the user experience on Android immensely.

So my possibly-controversial statement is:
Start your lifecycle methods and Commands with await Task.Run() and only use the main thread when necessary using Xamarin.Essential's MainThread.InvokeOnMainThreadAsync() method.

Please discuss whether you agree with this statement or not and whether it should be included in the documentation or in Xamarin's internal code.

On a lighter note: Please also critique my writing. I am a junior developer and this is the first time I've collected the courage to write something semi-professional for others to discuss. Any feedback is appreciated Image may be NSFW.
Clik here to view.
:smile:


Viewing latest article 40
Browse Latest Browse All 76418

Trending Articles