Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will an await in an OnAppearing mean the screen I am navigating to will show up immediately?

If I have this code:

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        await DoLengthDatabaseTaskAsync(); // takes 30 seconds
    }

Will the fact that it is an Async task mean that the screen appears quickly and does not wait on the database task to complete?

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        await CallAndForgetAboutOutputTaskAsync(); // takes 30 seconds
    }

How about if I am not concerned "call and forget" about the completion of the CallAndForgetAboutOutputTaskAsync() method.

Is there a way I can run CallAndForgetAboutOutputTaskAsync() in the background so the screen appears as soon as possible

like image 279
Alan2 Avatar asked Feb 21 '20 17:02

Alan2


People also ask

Why do we use await?

Async/Await makes it easier to write promises. The keyword 'async' before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.

How does async await work?

async and awaitInside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Does await make it synchronous?

Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.

What does await do typescript?

Asynchronous functions are prefixed with the async keyword; await suspends the execution until an asynchronous function return promise is fulfilled and unwraps the value from the Promise returned.


2 Answers

Yes and no.

OnAppearing means that the page has appeared on the screen and it performs immediately after that. So executing something there won't slow down anything.

However you should keep in mind that OnAppearing is executing on the UI thread and depending on the structure of your CallAndForgetAboutOutputTaskAsync() it may freeze your UI, but simple magic of Task.Run resolves the problem.

EDIT: So it should be like:

Task CallAndForget()
{
  return Task.Run(async() => await action());
}
like image 55
Ivan Ičin Avatar answered Oct 12 '22 20:10

Ivan Ičin


No.

OnAppearing happens

"immediately prior to the Page becoming visible."

The purpose of async/await is to allow UI-accessing code to be written in a linear fashion - each line must complete before the next line executes - WITHOUT blocking UI. That is, UI events still occur - between each await.

However, the async method (here, OnAppearing), won't return until all of its lines of code have executed.

That means the page won't display until after all the work is done.

The compiler turns the method into a sequence of tasks with continuations.


IMPORTANT CAVEAT:

It is still necessary for each awaited method ("DoLengthDatabaseTaskAsync") to be well-written with async/await as needed. Each of those methods is executed on the UI thread.

If that method goes a long time without itself having awaits, it will block UI during that time.

async/await does this for you:

  1. Allows you to write code that is still executing on the UI thread, so you can access UI elements without cross-threading issues.
  2. Allows UI events to occur BETWEEN each await line.
  3. If the awaited method is also async/await, allows UI events to occur between each of its internal await lines.

That's all async/await does. It doesn't magically eliminate all UI blocking.

And it isn't always a substitute for Task.Run. If you need to do a lengthy operation that doesn't access UI elements, use Task.Run. That runs code on a background thread, so you don't have to be concerned with lengthy operations that lack awaits.


Ivan's answer is one approach. Though the explanation given there is partly wrong.


However there is a simpler answer, given that you have a "fire and forget" situation, where you don't need an answer back:

protected override void OnAppearing()
{
    base.OnAppearing();
    Task.Run(CallAndForgetAboutOutputTaskAsync);
}

Code inside Task.Run is sent to a background thread. The Run immediately returns to the calling method.

Note that I've removed async from OnAppearing declaration. In this simple case, there is no use of await, and there is very little time spent on the ui thread, so there is no need for async (which generates a bit of extra code/overhead).

like image 36
ToolmakerSteve Avatar answered Oct 12 '22 20:10

ToolmakerSteve