将 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[]
,你可以在上面 WaitAll
或 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}");
您可以使用 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();
我有 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[]
,你可以在上面 WaitAll
或 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}");
您可以使用 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();