1

I have a collection of seeds

var seeds = new [] {1, 2, 3, 4};

From each seed I want to run an async method that performs some calculation with the seed:

async Task<int> Calculation(int seed);

My goal is to perform a select like this:

var results = from seed in seeds
              let calculation = await Calculation(seed)
              select new { seed, calculation };

Unfortunately, this syntax isn't allowed using LINQ.

How can I make the "results" variable contain both the seed and the calculation?

(I would appreciate any answer, but specially if it's using System.Reactive's Observable)

SuperJMN
  • 13,110
  • 16
  • 86
  • 185
  • http://stackoverflow.com/questions/21868087/how-to-await-a-list-of-tasks-asynchronously-using-linq Here answer by the Stephen Cleary, about it. – mybirthname Nov 03 '16 at 16:10

3 Answers3

3

Here's an Rx solution:

var seeds = new [] {1, 2, 3, 4};
var results = Observable.ToObservable(seeds)
    .SelectMany(async i => new { seed = i, calculation = await Calculation(i)})
    .ToEnumerable();
Shlomo
  • 14,102
  • 3
  • 28
  • 43
2

You could do the following using WhenAll static method:

var r= await Task.WhenAll(seeds.Select(async seed =>new {
                                                          Seed= seed,
                                                          Result = await Calculation(seed) 
                                                        }
                                      )
                         );  
ocuenca
  • 38,548
  • 11
  • 89
  • 102
1

Change your async function to return both the calculated number and the given seed:

public static async Task<Output> Calculation(int seed)
{
    return new Output { Seed = seed, Result = 0 };
}

public class Output
{
    public int Seed { get; set; }
    public int Result { get; set; }
}

Then use the linq to return a Task[] on which you can WaitAll or WhenAll: (WaitAll vs WhenAll)

var seeds = new[] { 1, 2, 3, 4 };

var tasks = seeds.Select(Calculation);
var results = await Task.WhenAll(tasks);

foreach (var item in results)
    Console.WriteLine($"seed: {item.Seed}, result: {item.Result}");
Community
  • 1
  • 1
Gilad Green
  • 36,708
  • 7
  • 61
  • 95