【问题标题】:LINQ foreach during list creation列表创建期间的 LINQ foreach
【发布时间】:2011-02-17 21:17:46
【问题描述】:

我有一个简单的 LINQ 语句,它构建了一个包含大约 80 亿个项目的巨大怪物列表。然后循环遍历每个项目并对该项目执行操作。问题是在完全创建列表之前甚至不会运行 foreach。是否可以使用 LINQ 并让它在构建每个项目时执行 foreach 而不是等待?

我没有在列表中做任何事情,比如排序。只是直接建立列表。

编辑:这可能看起来很奇怪,但我有一些带有多个数值的数据库行。我知道这些值的一些算术组合会产生我想要的数字,但不确定是哪个。因此,我创建了以下 LINQ:

(
 from I1 in Items
 from I2 in Items
 from I3 in Items
 from I4 in Items
 select new Item[] { I1, I2, I3, I4 }
).ToList().ForEach(x => CalculateValues(x);

我对 1 项然后 2 项进行了上述声明,依此类推。我的电脑在这 3 个项目上挂了一段时间,大约有 2800 万个项目。

我知道这样做效率低下,但我打算做一个快速的程序,以便在一夜之间运行。

【问题讨论】:

  • 你能放一些示例代码吗?
  • 是的,这是可能的。请提交一些代码,以便可以看到您要执行的操作。在进行 LINQ 处理时,必须小心不要强制完全枚举查询。

标签: linq list foreach


【解决方案1】:

听起来您想在构建列表时使用yield,如果可能的话,这样您就不会有 80 亿个项目在闲逛。

例如

public IEnumerable<MyItem> ListBuilder()
{
   while (stillBuilding)
   {
       yield return currentItem;
   }
}

然后foreach这个结果。

如果你想要一些并发/多线程的东西,那么它会更复杂,你可能应该有一个线程构建项目并将它们送入队列,而一个或多个消费者线程将项目从队列中拉出并执行操作。

【讨论】:

    【解决方案2】:

    不要调用ToList(),该方法会尝试将整个数据加载到内存中

    试试这个,

    var q = from I1 in Items
            from I2 in Items
            from I3 in Items
            from I4 in Items
            select new Item[] { I1, I2, I3, I4 };
    
    foreach(var x in q)
    {
        CalculateValues(x);
    }
    

    您的输入可能仍然很慢,但如果我是正确的,它会流式传输结果并一次处理一个。

    【讨论】:

    • 你是对的。这是一个更好的解决方案,因为它非常简单。我以前从未想过 ToList() 。我只是将它用于 ForEach 语句。
    猜你喜欢
    • 2019-01-02
    • 2012-01-30
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    相关资源
    最近更新 更多