Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# linq查询中的垃圾收集_C#_Linq_Garbage Collection_Deferred Execution - Fatal编程技术网

C# linq查询中的垃圾收集

C# linq查询中的垃圾收集,c#,linq,garbage-collection,deferred-execution,C#,Linq,Garbage Collection,Deferred Execution,我有一个关于如何在linq查询中处理垃圾收集的问题。 假设给我一个要处理的请求列表。每个请求都会生成一组非常大的数据,但随后会应用一个过滤器,仅保留来自每个请求负载的关键数据 //Input data List<request> requests; IEnumerable<filteredData> results = requests.Select(request => Process(request)).Select(data => Filter(data

我有一个关于如何在linq查询中处理垃圾收集的问题。 假设给我一个要处理的请求列表。每个请求都会生成一组非常大的数据,但随后会应用一个过滤器,仅保留来自每个请求负载的关键数据

//Input data
List<request> requests;
IEnumerable<filteredData> results = requests.Select(request => Process(request)).Select(data => Filter(data));
//输入数据
列出请求;
IEnumerable results=requests.Select(请求=>Process(请求)).Select(数据=>Filter(数据));
所以我知道每个数据项的查询都会延迟,直到每个过滤的数据项被请求为止,所以这很好。但是,中间内存密集的部分会一直持续到枚举完成吗

我希望发生的是,每个数据元素一经过过滤阶段就可以被垃圾收集,从而确保我有足够的内存来处理整个列表。是这样的,还是中间的可枚举项在整个查询结束之前保留所有内容?如果是的话,有没有linq的方法来处理这个问题



注意:Process()函数生成内存密集型数据。。。这就是我所担心的

只要
Process(…)
Filter(…)
的返回值不包含任何对内部使用的“大数据项”的引用,那么在处理每个元素后,该进程中使用的内存应该是无根的,并且是GC的候选内存


这并不意味着它将被收集,只是它将是一个候选人。如果内存压力很大,GC很可能会收集它。

很难回答您的问题,因为您发布的内容实际上不会编译(
Select
生成一个
IEnumerable
,但您正在将其分配到
列表中。假设
过滤器(数据)
函数返回一个
filteredData
,您必须对查询调用
ToList()
,将其存储在
结果中

请求
应该已经填充了数据。此列表将遵循正常的垃圾收集规则。我假设您担心的是
过程的结果。我不能具体地说会发生什么,因为我也不知道你的
过滤器
函数会做什么。除非
Filter
函数的结果保留对其参数的引用(换句话说,
Process
函数的结果),否则
Process
创建的对象在查询完成后将完全超出范围,并将遵循正常的垃圾收集规则


请记住,这些规则适用于托收资格。在应用程序的生命周期内,不保证收集任何对象。但是,结果是合格的,因此GC将能够收集它们。

垃圾收集器在.NET中非常具有攻击性,可以清理中间对象 当它们不再被引用时,甚至在循环内部。事实上,在某些情况下,它会清理仍然被引用的对象,如果它能看到它将永远不再被访问

运行此代码表明对象被清理得相当快,并且在查询完成之前不会挂起(它从来不会这样做):

公共类MyClass1{~MyClass1(){Console.WriteLine(“清理过的MyClass1”);}
公共类MyClass2{~MyClass2(){Console.WriteLine(“清理过的MyClass2”);}
公共课程
{
静态IEnumerable lotsOfObjects()
{
while(true)
收益率返回新MyClass1();
}
静态void Main()
{
var query=lotsOfObjects().Select(x=>foo(x));
foreach(查询中的MyClass2 x)
query.ToString();
}
静态MyClass2 foo(MyClass1 x)
{
返回新的MyClass2();
}
}
结果:

Cleaned up MyClass1 Cleaned up MyClass1 Cleaned up MyClass1 Cleaned up MyClass2 Cleaned up MyClass2 Cleaned up MyClass1 Cleaned up MyClass2 etc... 清理我的班级 清理我的班级 清理我的班级 清理我的班级2 清理我的班级2 清理我的班级 清理我的班级2 等
酷。我担心的是,从第一个select开始的中间枚举将保留数据,直到它被删除为止completed@tbischel:否-除了添加到集合中的引用之外,LINQ不会保存引用。只要没有引用,就可以进行GCD。修复了。。。不是从文件中复制的,所以是的,那是一个超站点 Cleaned up MyClass1 Cleaned up MyClass1 Cleaned up MyClass1 Cleaned up MyClass2 Cleaned up MyClass2 Cleaned up MyClass1 Cleaned up MyClass2 etc...