首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在dbQuery之后遇到OutOfMemoryException

在dbQuery之后遇到OutOfMemoryException
EN

Stack Overflow用户
提问于 2014-10-29 20:16:25
回答 1查看 59关注 0票数 0

我正在运行一个DB-query,它返回了相当多的特征(大约100000)。因为我遇到了前面提到的异常,所以我尝试将查询拆分为几个子查询。但是,由于所有这些子查询的结果都被写入到方法列表中,因此我仍然会遇到相同的异常。

因此,我想知道是否可以在每个子查询结束后,通过循环元素并返回每个元素来使用yield return

在检索到特性之后,我必须为每个特性创建一些新的自定义对象,所以我想知道在这种情况下使用yield是否会节省内存。

也许下面这句话会让你更清楚一些:

代码语言:javascript
复制
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只需要检索一次,而不是每个单独的对象(有更多的原因,但这是最方便的)。

EN

回答 1

Stack Overflow用户

发布于 2014-10-29 20:29:47

您应该避免将结果完全存储在列表中。主要思想是实例化每个昂贵的对象,处理它,然后立即处理它。

这意味着您的外部方法将如下所示:

代码语言:javascript
复制
foreach (var chunk in IDs.SplitIntoChunks(size: 500))
{
    foreach (var parcel in EnumerateComplexObjects(chunk))
    {
        yield return parcel;
    }
}

而且EnumerableComplexObjects也会使用yield return

代码语言:javascript
复制
IEnumerable<ComplexObject> EnumerateObjects(IEnumerable<int> ids)
{
    foreach (var id in ids)
    {
        using (var obj = CreateSingleComplexObject(id))
        {
            yield return obj;
        }
    }
}

请注意,一旦你这样做了,你甚至不再需要块:

代码语言:javascript
复制
foreach (var obj in EnumerateObjects(allIDs)
{
     Process(obj);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26630110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档