预编译异常:委托 'Action' 不接受 1 个参数

Precompile Exception: Delegate 'Action' does not take 1 arguments

我正在尝试修复从 public 存储库克隆的一些代码。这是缺少 await 运算符的 async 方法:

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
  return targetWorkItem.Relations?.Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index));
}

我正在尝试这个:

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
  return await Task.Run(o => targetWorkItem.Relations?.Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index)));
}

...但我在 IDE:

中遇到错误

Delegate 'Action' does not take 1 arguments

我发现了一些类似的讨论,但不幸的是 none 其中完全解决了 lambda 语法问题:

似乎预编译器将输入解释为 Action 而它应该将其视为 Func。但我认为语句 o => ... 可以指示两者之一。

我对 C# 不够熟悉,无法解决这个问题。有人可以帮忙吗?

如何告诉预编译器我要发送 Func 而不是 Action

嗯,编译错误的原因是 Task.Run 接受(非泛型)Action,这是一个不接受任何参数的委托。

您已尝试使用接受参数 o 的 lambda 调用 Task.Run,因此更改为此将消除错误:

Task.Run(() =>

圆括号 () 表示 lambda 表达式中没有参数。

话虽如此,在 Task.Run 中包装同步函数是一种反模式。

如果您的方法是完全同步的,理想情况下您应该这样公开它:

public IEnumerable<JsonPatchOperation> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
    return targetWorkItem.Relations?
        .Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index));
}

如果您无法更改签名,例如,如果您正在实现一个接口,那么请改用 Task.FromResult

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
    return Task.FromResult(targetWorkItem.Relations?
        .Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index)));
}

这只是将同步结果包装在 Task 对象中,而不是将 lambda 强制到线程池上的 运行。