Reputation: 1706
I am getting an error with the following code.
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>'.
}
This method calls the following function
private async Task<bool> FlushUrlAsync(bool recursive, string memoryCacheUrl)
{
return await someMagic(); //for clearity I removed the code.
}
It looks a lot like: Convert async lambda expression to delegate type System.Func<T>?, howevery, there solution won't /can't get it to work for me.
I had:
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;
Then resharper gave me the code that is provided, but just adding the async keyword doesn't work.
.Aggregate(true, async (current, memoryCacheUrl) => current && await FlushUrlAsync(recursive, memoryCacheUrl));
will give me the erorr: the return type of async method must be void, task or Task.
any ideas?
Upvotes: 1
Views: 7943
Reputation: 367
Use ContinueWith with TaskContinuationOptions,
Func<Exception, bool> handlerFunc = (Exception ex) =>
{
ex.HandleExceptionAsync().ContinueWith(async (result) =>
{
// all await operations can be called here
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion);
return true;
};
Upvotes: 0
Reputation: 205599
I would personally use the foreach
implementation, but answering the concrete question.
Without async
the Aggregate
overload used has the following signature:
bool Aggregate<bool, string>(bool seed, Func<bool, string, bool> func)
Note the func
parameter - it's a method receiving bool
and string
returning a bool
. The important part is that the type of the first argument is the same as the type of the result, as well as the type of seed
parameter.
Since async
lambda must return a Task
derived object. You need a bool
result, so let substitute it with Task<bool>
:
Task<bool> Aggregate<bool, string>(Task<bool> seed, Func<Task<bool>, string, Task<bool>> func)
which leads to the following solution:
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));
Upvotes: 4