完成“空”异步任务的不同方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完成“空”异步任务的不同方法相关的知识,希望对你有一定的参考价值。

我正在使用同时具有async方法的同步和Reconcile版本的库。

这些方法需要2个IEnumerables和3个代表,这些代表根据第一个列表中的值从第二个列表中调用添加,修改或删除的项目。

我的代码目前正在使用同步版本,我想将其转换为使用async版本。

因为我实际上不需要在委托中做任何删除工作,所以我在(item) => {}中传递deletedAction参数。

我发现了几个不同的版本,如何将其转换为散布在互联网上的“空”异步代理,以及StackOverflow,但我不确定它们之间的区别,或者哪种方式最正确。

发送“空”异步委托作为参数的这些方法之间的区别是什么,以及哪些是当前“最正确”的方式?有没有更好的方法让我错过了?

  1. async (item) => {await Task.CompletedTask;}
  2. async (item) => {await Task.FromResult(0);}
  3. async (item) => {await Task.Yield;}
  4. async (item) => {await Task.Delay(0);}(这个似乎是一个糟糕的选择,但我包括它是为了完整性)

它们似乎都在工作,除了Task.CompletedTask,但这是因为我使用的框架是.Net Framework的4.5版本,并且在该版本中不存在。

答案

所以没有一个是正确的。你应该做的是:

item => Task.CompletedTask

或者,在旧版本的框架上:

item => Task.FromResult(0)

你没有理由让方法async等待已经完成的任务。它只是增加了状态机的开销,以便什么都不做。

在返回完成的任务之前,使用Delay只需要额外的间接层。它没有添加任何有用的东西,除了模糊你试图返回一个完整的Task的事实。它还依赖于一个未记录的实现细节,当超时为Delay时,0返回一个已完成的任务,这在可能的情况下应该避免。

使用Yield是迄今为止最糟糕的。 Yield的全部意义在于它不会被视为立即完成。 Yield的目标是导致继续被添加和解雇,而不是被观察到的任务立即完成。它专门用于避免您想要利用的优化。

以上是关于完成“空”异步任务的不同方法的主要内容,如果未能解决你的问题,请参考以下文章

异步任务类完成后如何更改文本视图的值(在片段中)?

自动挂钩到 Activity 生命周期方法的异步任务库

当前一个片段中的某些任务完成时如何通知另一个片段中的适配器

屏幕方向期间片段内的异步任务

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段

从同步代码调用异步方法并阻塞直到任务完成的正确方法是啥? [复制]