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

问题描述 投票:5回答:1

我正在使用同时具有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版本,并且在该版本中不存在。

c# async-await
1个回答
6
投票

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

item => Task.CompletedTask

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

item => Task.FromResult(0)

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.