无法将异步lambda表达式转换为委托类型&#39; Func <bool,string,=“”bool =“”>&#39;

时间:2016-10-27 08:29:52

标签: c# asynchronous lambda

我收到以下代码的错误。

public async Task<bool> FlushUrlAsync(Uri url, bool recursive, CancellationToken token = default(CancellationToken))
{
    _serverPortsConfig.CacheServerPorts
        .Select(cacheServerPort => $"http://{url.Host}:{cacheServerPort}{url.AbsolutePath}")
        .Aggregate(true, (current, memoryCacheUrl) => current && await FlushUrlAsync(recursive, memoryCacheUrl)); //<--- produces the next error:
    // Cannot convert async lambda expression to delegate type
    // 'Func<bool, string, bool>'. An async lambda expression may return 
    // void, Task or Task<T>, none of which are convertible to
    // 'Func<bool, string, bool>'.
 }

此方法调用以下函数

private async Task<bool> FlushUrlAsync(bool recursive, string memoryCacheUrl)
{
    return await someMagic(); //for clearity I removed the code.
}

它看起来很像:Convert async lambda expression to delegate type System.Func<T>?,如何,解决方案赢得了/不能让它为我工作。

我有:

var result = true;
foreach (var cacheServerPort in _serverPortsConfig.CacheServerPorts)
{
    var memoryCacheUrl = $"http://{url.Host}:{cacheServerPort}{url.AbsolutePath}";
    result = result && await FlushUrlAsync(memoryCacheUrl, recursive);
}

return result;

然后resharper给了我提供的代码,但只是添加async关键字不起作用。

.Aggregate(true, async (current, memoryCacheUrl) => current && await FlushUrlAsync(recursive, memoryCacheUrl));

会给我一个erorr:async方法的返回类型必须是void,task或Task。

任何想法?

1 个答案:

答案 0 :(得分:3)

我个人会使用foreach实现,但回答具体问题。

如果没有async,则使用的Aggregate重载具有以下签名:

bool Aggregate<bool, string>(bool seed, Func<bool, string, bool> func)

注意func参数 - 它是一种接收boolstring返回bool的方法。重要的是,第一个参数的类型与结果的类型以及seed参数的类型相同。

由于async lambda必须返回Task派生对象。您需要bool结果,因此请将其替换为Task<bool>

Task<bool> Aggregate<bool, string>(Task<bool> seed, Func<Task<bool>, string, Task<bool>> func)

导致以下解决方案:

return await _serverPortsConfig.CacheServerPorts
    .Select(cacheServerPort => $"http://{url.Host}:{cacheServerPort}{url.AbsolutePath}")
    .Aggregate(Task.FromResult(true), async (current, memoryCacheUrl) => 
        await current && await FlushUrlAsync(recursive, memoryCacheUrl));