I have a private function which takes IEnumerable<Func<Task<T>>>
as input. I'm having IEnumerable<Task<T>>
to be passed. How to convert IEnumerable<Task<T>>
to IEnumerable<Func<Task<T>>>
?
Code Sample:
private static async Task<IEnumerable<T>> ParallelizeAsync<T>(IEnumerable<Func<Task<T>>> funcs, int maxParallelism)
{
var sem = new SemaphoreSlim(maxParallelism, maxParallelism);
var result = funcs.Select(async f =>
{
await sem.WaitAsync();
var r = await f();
sem.Release();
return r;
});
return await Task.WhenAll(result);
}
var functasks = Enumerable.Range(1, 5).Select(async x => await Task.FromResult(x));
var help = ParallelizeAsync<IEnumerable<int>>(functasks, 10);
I'm getting the following error,
cannot convert from 'System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task>' to 'System.Collections.Generic.IEnumerable<System.Func<System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable>>>'
Am I missing some cast?
CodePudding user response:
So, you'll want to create a Func
which, when called, returns that already-completed Task
you constructed. The easist way is simply:
() => theTask
So either:
var functasks = Enumerable.Range(1, 5).Select(x => () => Task.FromResult(x));
Or given functasks
:
var help = ParallelizeAsync<int>(functasks.Select(x => () => x), 10);
Your other problem is that you're calling:
var help = ParallelizeAsync<IEnumerable<int>>(functasks, 10)
Since the signature of ParallelizeAsync
is:
private static async Task<IEnumerable<T>> ParallelizeAsync<T>(IEnumerable<Func<Task<T>>> funcs, int maxParallelism)
This means that T
is an IEnumerable<int>
, so ParallelizeAsync
is expecting an IEnumerable<Func<Task<IEnumerable<int>>>>
. This doesn't match the rest of your question.
You probably intended to call ParallelizeAsync<int>(...)
.
CodePudding user response:
var l = new List<Task<bool>>();
var f = new List<Func<Task<bool>>>();
f = l.Select<Task<bool>, Func<Task<bool>>>(x => () => x).ToList();
for you, just change this line
var help = ParallelizeAsync<IEnumerable<int>>(functasks.Select(t => () => t) , 10);
CodePudding user response:
You need to pass a function to Select
that returns another function:
var functasks = Enumerable.Range(1, 5)
.Select(x => async () => await Task.FromResult(x));
And in this simple example, async
/ await
are superfluous:
var functasks = Enumerable.Range(1, 5).Select(x => () => Task.FromResult(x));
Note that you are also calling ParallelizeAsync
incorrectly; by providing IEnumerable<int>
as the generic argument, funcs
becomes IEnumerable<Func<Task<IEnumerable<int>>>>
.
You should simply be passing int
:
var help = ParallelizeAsync<int>(functasks, 10);
Or let type inference do the work:
var help = ParallelizeAsync(functasks, 10);