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

时间:2018-03-06 15:54:04

标签: c# async-await

我使用的库同时具有async Reconcile方法的IEnumerables版本。

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

我的代码目前正在使用同步版本,我想将其转换为使用(item) => {}版本。

由于我实际上不需要在代理中进行任何删除操作,因此我会在deletedAction传递async (item) => {await Task.CompletedTask;}参数。

我找到了几个不同的版本,如何将其转换为"空"异步委托散布在互联网上,并且跨越StackOverflow,但我不确定它们之间的区别,或者哪种方式最正确。

这些发送"空"的方法有何不同? async delegate作为参数,其中哪一个是当前"最正确的"办法?有没有更好的方法让我错过了?

  1. async (item) => {await Task.FromResult(0);}
  2. async (item) => {await Task.Yield;}
  3. async (item) => {await Task.Delay(0);}
  4. Task.CompletedTask(这个似乎是一个糟糕的选择,但我还是为了完整性而将其包括在内)
  5. 它们似乎都在工作,除了%input.prime.campaign_chkbox{:type=>"checkbox", "data-type" => 'payrolloption',:id=>"#{element['id']}", :checked => ("#{element['payrolloption']}"=='1' ? true : false) } ,但这是因为我使用的框架是.Net Framework的4.5版本,并且它不存在于版本

1 个答案:

答案 0 :(得分:6)

所以它们都不正确。你应该做的是:

item => Task.CompletedTask

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

item => Task.FromResult(0)

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

在返回完成的任务之前,使用Delay只需要额外的间接层。除非模糊了您尝试返回已完成的Task这一事实,否则它不会添加任何有用的内容。它还依赖于未记录的实现细节,Delay在超时为0时返回已完成的任务,这在可能的情况下应该避免。

使用Yield是最糟糕的。 Yield的整个是它不会立即被观察到完成。 Yield目标将导致继续被添加和触发,而不是被观察为立即完成的任务。它专门用于避免您希望利用的优化