我使用的库同时具有async
Reconcile
方法的IEnumerables
版本。
这些方法需要2个async
和3个代表,这些代表将根据第一个列表中的值从第二个列表中调用添加,修改或删除的项目。
我的代码目前正在使用同步版本,我想将其转换为使用(item) => {}
版本。
由于我实际上不需要在代理中进行任何删除操作,因此我会在deletedAction
传递async (item) => {await Task.CompletedTask;}
参数。
我找到了几个不同的版本,如何将其转换为"空"异步委托散布在互联网上,并且跨越StackOverflow,但我不确定它们之间的区别,或者哪种方式最正确。
这些发送"空"的方法有何不同? async delegate作为参数,其中哪一个是当前"最正确的"办法?有没有更好的方法让我错过了?
async (item) => {await Task.FromResult(0);}
async (item) => {await Task.Yield;}
async (item) => {await Task.Delay(0);}
Task.CompletedTask
(这个似乎是一个糟糕的选择,但我还是为了完整性而将其包括在内)它们似乎都在工作,除了%input.prime.campaign_chkbox{:type=>"checkbox", "data-type" => 'payrolloption',:id=>"#{element['id']}", :checked => ("#{element['payrolloption']}"=='1' ? true : false) }
,但这是因为我使用的框架是.Net Framework的4.5版本,并且它不存在于版本
答案 0 :(得分:6)
所以它们都不正确。你应该做的是:
item => Task.CompletedTask
或者,在旧版本的框架上:
item => Task.FromResult(0)
您没有理由让方法async
只是等待已经完成的任务。它只是增加了状态机的开销,以便什么都不做。
在返回完成的任务之前,使用Delay
只需要额外的间接层。除非模糊了您尝试返回已完成的Task
这一事实,否则它不会添加任何有用的内容。它还依赖于未记录的实现细节,Delay
在超时为0
时返回已完成的任务,这在可能的情况下应该避免。
使用Yield
是最糟糕的。 Yield
的整个点是它不会立即被观察到完成。 Yield
的目标将导致继续被添加和触发,而不是被观察为立即完成的任务。它专门用于避免您希望利用的优化。