【发布时间】:2019-03-15 04:43:25
【问题描述】:
我已经开始学习函数式编程,虽然链接方法在正常情况下看起来很棒(在我看来),但在处理 async/await 时它真的很难看
await (await (await CosmosDbRepository<ApplicationProcess>
.GetItemAsync(param.ProcessId))
.Historize(() => _analyseFinanciereService.ProcessAsync(),
ProcessStepEnum.Application))
.Notify(p => p.GetLastStep());
有什么办法可以消除这种噪音吗?
编辑:
public static async Task<ApplicationProcess> Historize(
this ApplicationProcess process,
Func<Task> fn,
ProcessStepEnum stepEnum)
{
var dateStart = DateTime.UtcNow;
var error = string.Empty;
try
{
await fn();
return process;
}
…
public static async Task Notify<TResult>(
this ApplicationProcess process,
Func<ApplicationProcess, TResult> fn)
...
Edit2 : 带有接受任务的扩展方法
await CosmosDbRepository<ApplicationProcess>
.GetItemAsync(param.ProcessId)
.HistorizeAsync(() => _analyseFinanciereService.ProcessAsync(), ProcessStepEnum.Application)
.NotifyAsync(p => p.GetLastStep());
这就是我一直在寻找的东西,即使我对最新的 cmets 感到困惑
【问题讨论】:
-
你没有。如果一个人需要另一个方法的结果,不要链接这些方法。或者将它们转换为接受
Task<Whatever>作为其第一个成员的扩展方法 -
我通常会为此目的使用Facade Design Pattern!
-
@Panagiotis Kanavos 这就是我所做的,也许不是我应该做的?我已经编辑了原始帖子以显示链接方法的实际签名
-
@XavSc 首先,它是 await 将实际的异步方法与延续联系起来 - 无论它之后发生什么。其次,扩展方法应该是
Historize( this Task<ApplicationProcess>process, ...)` 以允许直接链接。 每个 这样的方法必须使用await process来获取实际的进程对象。但是,您希望通过链接这样的方法获得什么?fn是做什么的,它依赖于process吗?如果要创建处理步骤的管道,请使用 Dataflow 库 -
@XavSc 这样的链接方法不会提高代码的可读性,恰恰相反。它也不会创建管道,它只是一系列异步调用。通过使用 Dataflow 块创建真正的管道,您可以使用输入/输出缓冲、背压、可配置的步骤并行性来真正执行步骤。
标签: c# .net async-await method-chaining