我正在运行一个DB-query,它返回了相当多的特征(大约100000)。因为我遇到了前面提到的异常,所以我尝试将查询拆分为几个子查询。但是,由于所有这些子查询的结果都被写入到方法列表中,因此我仍然会遇到相同的异常。
因此,我想知道是否可以在每个子查询结束后,通过循环元素并返回每个元素来使用yield return。
在检索到特性之后,我必须为每个特性创建一些新的自定义对象,所以我想知道在这种情况下使用yield是否会节省内存。
也许下面这句话会让你更清楚一些:
foreach (var chunk in IDs.chunk(500))
{
List<ComplexObject> result = new List<ComplexObject>():
// ...
// make a (sub-)query on every chunk to retrieve 500 objects at once
// ..
// now we have up to 500 ComplexObjects within result
foreach (var parcel in result)
{
yield return parcel;
parcel.Release(); // release COM-object
}
}其中chunk是500个元素(ID)的(子)-collection。
然后,我在foreach中循环从该方法检索到的结果,并从它们创建自定义对象。
编辑:我也可以一个接一个地查询和处理每个ComplexObject,实际上这比检索一堆比如说500个元素要慢得多,因为MetaData只需要检索一次,而不是每个单独的对象(有更多的原因,但这是最方便的)。
发布于 2014-10-29 20:29:47
您应该避免将结果完全存储在列表中。主要思想是实例化每个昂贵的对象,处理它,然后立即处理它。
这意味着您的外部方法将如下所示:
foreach (var chunk in IDs.SplitIntoChunks(size: 500))
{
foreach (var parcel in EnumerateComplexObjects(chunk))
{
yield return parcel;
}
}而且EnumerableComplexObjects也会使用yield return
IEnumerable<ComplexObject> EnumerateObjects(IEnumerable<int> ids)
{
foreach (var id in ids)
{
using (var obj = CreateSingleComplexObject(id))
{
yield return obj;
}
}
}请注意,一旦你这样做了,你甚至不再需要块:
foreach (var obj in EnumerateObjects(allIDs)
{
Process(obj);
}https://stackoverflow.com/questions/26630110
复制相似问题