繁体   English   中英

实体框架OutOfMemoryException的说明和解决方案

[英]Explanation and solution for Entity Framework OutOfMemoryException

假设我有一个这样的DbContext &实体:

class Node
{
    public int Id { get; set; }

    public string Name { get; set; }
    public int ParentId { get; set; }

    [ForeignKey("ParentId")]
    public Node Parent { get; set; }

    public virtual ICollection<Node> Nodes { get; set; }
}

class MyContext : DbContext
{
    public DbSet<Node> Nodes { get; set; }

    public void ScanChildren(Node parentNode, Action<Node> onFound)
    {
        var query = this.Nodes.Where(X => X.ParentId == parentNode.Id);
        var children = query.ToArray();

        // if I comment this line I get OOME
        System.Windows.Forms.Application.DoEvents();

        foreach (var child in children)
        {               
            onFound(child);
            ScanChildren(child, onFound);
        }
    }
}

static class test
{
    static void ScanTest()
    {
        using (var db = new MyContext())
        {
            var nodeToScan = db.Nodes.First();
            var childrenlist = new List<Node>();
            db.ScanChildren(nodeToScan, x => childrenlist.Add(x));
        }
    }
}

我使用Sqlite databese。 Nodes表包含600000条记录,我调用ScanTest函数,当我调用ScanChildren函数时,得到OutOfMemoryException nodeToScan有25000 nodeToScan

我的问题是:当我添加以下代码行时,为什么不会发生OutOfMemoryException

System.Windows.Forms.Application.DoEvents();

还有更好的方法来避免OutOfMemoryException吗?

关于DoEvents,在msdn.microsoft.com/zh-cn/library/上,您可以阅读“通常情况下,您在循环中使用此方法来处理消息。”,因此直观地说,我认为您已经运行了这么长时间在阻塞的UI线程中运行ScanChildren的进程,如果是这样的话,则可能会阻止某些事件消息的正常处理流程,这些事件消息正在缓冲区中排队,最终导致内存不足异常。 尝试在后台线程中运行查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM