我在使用LINQ-To-SQL方面遇到了一些问题。我在Windows服务中使用它来进行一些处理,我正在循环浏览大量的数据,我正在从上下文中撤回。是的 - 我知道我可以通过存储过程来实现这一点,但有理由认为这不是理想的解决方案。

无论如何,我看到的基本上是即使在我调用 context.SubmitChanges()之后内存也没有被释放。所以我最终不得不做各种各样奇怪的事情,比如只追回100条记录,或创建几个上下文并让它们都做单独的任务。如果我保留相同的 DataContext 并稍后将其用于其他调用,它只会占用越来越多的内存。即使我在“ var tableRows ”上调用 Clear()查询返回给我的数组,将其设置为null,并调用 SYstem.GC.Collect() - 它仍然不释放内存。

现在我已经阅读了一些关于如何快速使用 DataContexts 并快速处理它们的内容,但似乎它们应该是强制上下文转储其所有数据的一种方式(或者在特定点的所有跟踪数据),以保证内存是免费的。

任何人都知道哪些步骤可以保证释放内存?

有帮助吗?

解决方案

如果您不需要对象跟踪,请将 DataContext.ObjectTrackingEnabled 设置为 false 。如果你确实需要它,你可以使用反射来调用内部的 DataContext.ClearCache(),虽然你必须要知道,因为它的内部,它会在框架的未来版本中消失。据我所知,框架本身不使用它,但它 清除对象缓存。

其他提示

DataContext跟踪它所获取的所有对象。在收集垃圾之前不会释放它。此外,当它实现 IDisposable 时,您必须调用 Dispose 或使用 using 语句。

这是正确的方法:

using(DataContext myDC = new DataContext)
{
  //  Do stuff
} //DataContext is disposed

正如David指出的那样,你应该使用using块处理DataContext。

您的主要关注点似乎是创建和处理一堆DataContext对象。这就是linq2sql的设计方式。 DataContext意味着具有较短的生命周期。由于您从数据库中提取了大量数据,因此有大量内存使用是有意义的。通过以块为单位处理数据,您处于正确的轨道上。

不要害怕创建大量的DataContexts。它们旨在以这种方式使用。

谢谢大家 - 我将查看ClearCache方法。仅仅为了澄清(对于未来的读者),我获得内存使用的情况是这样的:

using(DataContext context = new DataContext())
{
   while(true)
   {
      int skipAmount = 0;
      var rows = context.tables.Select(x => x.Dept == "Dept").Skip(skipAmount).Take(100);

      //break out of loop when out of rows

      foreach(table t in rows)
      {
         //make changes to t   
      }

      context.SubmitChanges();
      skipAmount += rows.Count();

      rows.Clear();
      rows = null;

      //at this point, even though the rows have been cleared and changes have been
      //submitted, the context is still holding onto a reference somewhere to the
      //removed rows.  So unless you create a new context, memory usuage keeps on growing
   }
}

我遇到了类似的问题。在我的例子中,帮助将 DataContext.ObjectTrackingEnabled 的属性设置为false。 但它只适用于迭代行的情况,如下所示:

using (var db = new DataContext())
{
    db.ObjectTrackingEnabled = false;
    var documents = from d in db.GetTable<T>()
                     select d;
    foreach (var doc in documents)
    {
        ...
    }
}

例如,如果在查询中使用方法ToArray()或ToList() - 没有效果

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top