0

My OnAppearing code looks like this. I don't understand what this is added for:

`await Task.Yield()`

Can someone explain what this does?

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        Utils.SetState(Settings.mode.Text(), vm.Mode);
        vm.CfsLabel = Settings.cfs.Text();

        SetMode(Settings.mode.Text());
        Subscribe();
        ContentPageStack.IsVisible = true;
        if (!openedOnce)
        {
            // can someone explain what the following line
            // is doing here in the code. What's the Task
            // that it refers to and what does Yield do? 
            await Task.Yield();

            await scroll.ScrollToAsync(0, 0, false);
            openedOnce = true;
        }
        if (App.devIsUser)
            Analytics.TrackEvent(VersionTracking.CurrentVersion + " - On Appearing - home page");
    }
Alan2
  • 23,493
  • 79
  • 256
  • 450
  • Possible duplicate of [When would I use Task.Yield()?](https://stackoverflow.com/questions/22645024/when-would-i-use-task-yield) – Paramjit May 23 '19 at 10:41

2 Answers2

1

In this particular case, await Task.Yield does nothing useful. It is probably a misguided attempt to process Win32 messages like WM_PAINT. I.e., a "poor man's DoEvents".

await Task.Yield is used to force asynchrony. It's a way of forcing await to behave asynchronously, returning to the caller. It also immediately queues the remainder of the method to run.

The reason this doesn't work as a "poor man's DoEvents" is because the Win32 message queue is prioritized. So this is what the await Task.Yield actually does in this particular instance:

  • Queues the continuation of the async method to the current context (the UI SynchronizationContext), which places the continuation into the Win32 message queue.
  • Returns from the async method. Since this is an event handler, this returns to the Win32 message processing loop.
  • The Win32 message process loop pulls the next message from its queue. Since the queue is prioritized, it will always skip over regular Win32 messages and take the continuation message.
  • The loop processes the message, which runs the continuation of the async method, so the event handler resumes executing right where it left off.
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

I think the Microsoft docs give you a clear picture of what it does, When you read about Task.Yield its says:

Creates an awaitable task that asynchronously yields back to the current context when awaited.

Returns YieldAwaitable

A context that, when awaited, will asynchronously transition back into the current context at the time of the await. If the current SynchronizationContext is non-null, it is treated as the current context. Otherwise, the task scheduler that is associated with the currently executing task is treated as the current context.

What this basically means is when you use await Task.Yield in an async method it will force the method to complete asynchronously. And if there is a Synchronization Context available it will execute the remainder of the method's execution back to that context.

Note: The synchronization context that is present on a UI thread in most UI environments will often prioritize work posted to the context higher than input and rendering work. For this reason, do not rely on await Task.Yield(); to keep a UI responsive.

FreakyAli
  • 13,349
  • 3
  • 23
  • 63