在Xamarin Forms OnAppearing中时,等待Task.Yield会做什么?

时间:2019-05-23 09:54:59

标签: xamarin xamarin.forms

我的OnAppearing代码如下所示。我不明白这是为什么添加的:

`await Task.Yield()`

有人可以解释这是什么吗?

    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");
    }

2 个答案:

答案 0 :(得分:1)

在这种特殊情况下, await Task.Yield没有任何用处。处理诸如WM_PAINT之类的Win32消息可能是错误的尝试。即“穷人的DoEvents”。

await Task.Yield用于force asynchrony。这是强制await异步执行并返回到调用方的一种方式。它还会立即将其余的方法排入队列。

之所以不能作为“穷人的DoEvents”,是因为Win32消息队列具有优先级。因此,await Task.Yield在此特定实例中实际上是这样做的:

  • async方法的延续性排队到当前上下文(UI SynchronizationContext),这将延续性放入Win32消息队列中。
  • async方法返回。由于这是事件处理程序,因此将返回到Win32消息处理循环。
  • Win32消息处理循环从其队列中提取下一条消息。由于对队列进行了优先级排序,因此它将始终跳过常规的Win32消息并接收继续消息。
  • 循环处理消息,该消息将继续执行async方法,因此事件处理程序将从中断处继续执行。

答案 1 :(得分:0)

我认为Microsoft文档为您提供了清晰的图像,当您阅读有关Task.Yield的内容时:

  

创建一个等待的任务,等待时异步地返回当前上下文。

     

返回   等待收益

     

在等待await时将异步转换回当前上下文的上下文。如果当前SynchronizationContext为非null,则将其视为当前上下文。否则,与当前正在执行的任务关联的任务计划程序将被视为当前上下文。

这基本上意味着在异步方法中使用await Task.Yield时,它将强制该方法异步完成。并且如果有Synchronization Context可用,它将在该上下文中执行该方法执行的其余部分。

注意:在大多数UI环境中,UI线程上存在的同步上下文通常会将发布到上下文的工作的优先级高于输入和呈现工作。因此,请勿依赖于等待Task.Yield();。保持用户界面的响应速度。