c# - 选择异步函数的更好方法?

标签 c# .net linq select func

我一直在重构我的项目中的一个常见模式,发现它不像使用 LINQ Select 那样简单。到异步函数。

对于上下文,这是当前的完成方式。

async Task<ICollection<Group>> ExecuteQueryGroupsForDomain(DomainInfo domain, int batchSize, CancellationToken ct)
{
    try
    {
        return await BlahBlahActuallyGoGetGroupsForDomainHere(domain, batchSize, ct);
    }
    catch (Exception e)
    {
        return null;
    }
}

var executeQueries = new List<Func<CancellationToken, Task<ICollection<Group>>>>();

domains.ForEach(domain =>
    executeQueries.Add(async (ct) =>
        await ExecuteQueryGroupsForDomain(domain, 123, ct)));


现在,如果我尝试替换 ForEach使用 LINQ 的循环部分:
var executeQueries = domains.Select(domain =>
    async (ct) => await ExecuteQueryGroupsForDomain(domain, 123, ct));

它提示Type arguments cannot be inferred by the usage这让我相信我没有从 Select 返回任何东西,但我显然要返回 Func我想。

有没有更好的方法来创建 Func 列表?的,理想情况下避免显式转换?还有什么解释为什么编译器在 Select 时无法推断类型? 'd async 方法清楚地告诉它应该是什么类型?

要清楚,我确实需要通过 CancellationTokenFunc是因为它是与外部 token 不同的 token (具体来说,它是将外部 token 与另一个内部 token 联系起来的链接 token )。

最佳答案

问题在于选择的返回,因为编译器不清楚返回的类型是什么。所以,你需要明确返回的类型,这里有两种方法:

executeQueries = domains.Select(domain => 
    new Func<CancellationToken, Task<ICollection<Group>>>(token => 
        this.ExecuteQueryGroupsForDomain(domain, 123, token))).ToList();

executeQueries = domains
    .Select<DomainInfo, Func<CancellationToken, Task<ICollection<Group>>>>(domain =>
        ct => this.ExecuteQueryGroupsForDomain(domain, 123, ct)).ToList();

==================================================== =====================

编辑1:
编译器无法从 lambda 表达式推断类型,因为 lambda 只是匿名方法的简写,而不是类型。因此,您需要明确并指出方法的返回类型,如果返回是基委托(delegate)或其他委托(delegate)类型,如 Action、Func 等。查看 this其他答案,其中解释了基于 C# 4 规范的错误编译器。

如果您需要将原始代码转换为更具可读性的内容,我认为没有另一种更具可读性的方式。以下是可以编写代码的其他方式:
foreach (var domain in domains) {
    executeQueries.Add(token => this.ExecuteQueryGroupsForDomain(domain, 123, token));
}
executeQueries.AddRange(domains
    .Select(domain => (Func<CancellationToken, Task<ICollection<Group>>>) (token => 
        this.ExecuteQueryGroupsForDomain(domain, 123, token))));
executeQueries =
    (from domain in domains
    select new Func<CancellationToken, Task<ICollection<Group>>>(token => 
        this.ExecuteQueryGroupsForDomain(domain, 123, token))).ToList()

关于c# - 选择异步函数的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61585021/

相关文章:

c# - Winform : Placing a panel over multiple panels

c# - 要求包含支持接口(interface)的引用

c# - 使用 Fluent NHibernate 自动映射字典时,不考虑元素列长度

.net - VB.NET:TAB 的标识符?

c# - LINQ连接多表

c# - npgsql 2.1.3 和 EF 6 : Could not determine storage version; a valid storage connection or a version hint is required

c# - 如何测试 EF 模型

c# - 文件拖放事件处理程序中的 MessageBox 导致 Windows 资源管理器卡住

c# - LINQ 查询在请求字节时返回 null

c# - 如何在 LINQ 中组合对象属性中的列表?