将 LINQ 与异步混合(从种子获取有效负载)

Mixing LINQ with async (getting payload from a seed)

我有 collection 个种子

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

我想从每个种子 运行 一个用种子执行一些计算的异步方法:

async Task<int> Calculation(int seed);

我的目标是执行这样的 select:

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

遗憾的是,使用 LINQ 不允许使用此语法。

如何使 "results" 变量同时包含种子和计算?

(我将不胜感激任何答案,但特别是如果它使用 System.Reactive 的 Observable

将您的异步函数更改为 return 计算数字和给定数字 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; }
}

然后使用 linq 来 return 一个 Task[],你可以在上面 WaitAllWhenAll: (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}");

您可以使用 WhenAll 静态方法执行以下操作:

var r= await Task.WhenAll(seeds.Select(async seed =>new {
                                                          Seed= seed,
                                                          Result = await Calculation(seed) 
                                                        }
                                      )
                         );  

这是一个 Rx 解决方案:

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