.Except/Yield返回内存不足异常

Car*_*rra 2 c# linq out-of-memory yield-return

我使用Linq的Except语句耗尽内存.

例:

var numbers = Enumerable.Range(1, 10000000);
int i=0;
while (numbers.Any())
{
    numbers = numbers.Except(new List<int> {i++});
}
Run Code Online (Sandbox Code Playgroud)

我反编译了这个方法,这样做同样也给出了内存不足的异常.

var numbers = Enumerable.Range(1, 10000000);
int i=0;
while (numbers.Any())
{
   numbers = CustomExcept(numbers, new List<int>{i++});
}
private IEnumerable<int> CustomExcept(IEnumerable<int> numbers, IEnumerable<int> exceptionList)
{
    HashSet<int> set = new HashSet<int>();
    foreach (var i in exceptionList)
    {
        set.Add(i);
    }
    foreach (var i in numbers)
    {
        if (set.Add(i))
        {
           yield return i;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:为什么会抛出内存异常?

我希望垃圾收集器能够清理未使用的HashSet.

Han*_*ing 5

当你进入i==10时numbers.Any(),"数字"不是从10到1000万的数字列表,而是:

Enumerable.Range(1, 10000000)
   .Except({0})
   .Except({1})
   .Except({2})
   // (etc)
   .Except({9})
Run Code Online (Sandbox Code Playgroud)

而所有那些"Excepts"都有他们自己的hashset非常活跃.所以垃圾收集没什么.

你将不得不添加一些.ToList()s来真正执行那些Excepts并给垃圾收集器一些机会.