gpt4 book ai didi

c# - 预加载下一个 IEnumerable

转载 作者:行者123 更新时间:2023-11-30 14:59:25 25 4
gpt4 key购买 nike

给定类结构:

public class Foo
{
public IEnumerable<Bar> GetBars()
{
for(int i = 0; i < 1000; i++)
{
Thread.Sleep(1000);
yield return new Bar() { Name = i.ToString() };
}
}
}

public class Bar
{
public string Name { get; set; }
}

我有 IEnumerable<Foo> 的列表以及检索下一个 Bar 的时间在 GetBars() 内方法非常慢(上面用 Thread.Sleep(1000) 模拟)。

我想做以下事情:

myFoo.AsParallel().SelectMany(foo => foo.GetBars().Select(bar => bar.Name))

但是因为延迟我想继续预载下一个Bar每个值 Foo然后有 IEnumable<Bar>对于每个 Foo按照可访问的顺序相互合并。

我一直在研究 Tpl Dataflow async nuget 库(特别是 TransformBlock 和较小程度上的 ActionBlock),但找不到任何可以帮助我完成我想做的事情的东西。

最佳答案

问题是,无论并行与否,在获得第一个 Bar 对象之前,您仍然无法开始获得第二个 Bar 对象。仅当您通过 LINQ 功能对每个对象进行长时间运行处理时,使用 PLINQ 才真正有帮助,如果延迟是由底层 IEnumerable 引起的,则没有帮助。

一个选项是返回一系列 Task 对象,这样移动迭代器只需很少的时间:

public async Task<Bar> GenerateFoo()
{
await Task.Delay(1000);
return new Bar() { Name = i.ToString() };
}

public IEnumerable<Task<Bar>> GetBars()
{
for(int i = 0; i < 1000; i++)
{
yield return GenerateFoo();
}
}

使用该代码意味着移动迭代器只会开始 Bar 的生成,而不是等到它完成。一旦你有了它,你就可以向每个任务添加延续来处理每个 Bar,或者你可以使用诸如 Task.WaitAllTask 之类的方法.WhenAll 等待它们全部完成。

关于c# - 预加载下一个 IEnumerable<T> 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16793897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com