0

我有一个 WPF 应用程序,它在内存不足后停止运行......
它基本上是一个显示节点的 TreeView,它们是 Linq To Sql 或生成的类 ICTemplates.Segment 的实例。在 OR 设计器中,大约有 20 个表通过关联间接链接到该类。

<TreeView Grid.Column="0" x:Name="tvwSegments" 
                      ItemsSource="{Binding}" 
                      SelectedItemChanged="OnNewSegmentSelected"/>
<HierarchicalDataTemplate DataType="{x:Type local:Segment}" ItemsSource="{Binding Path=Children}"> 
...

// code behind, set the data context based on user-input (Site, Id)
KeeperOfControls.DataContext = from segment in tblSegments
   where segment.site == iTemplateSite && segment.id == iTemplateSid
   select segment;

我在段类中添加了一个名为 Children 的显式属性,该类使用父子记录查找另一个表。

public IEnumerable<Segment> Children
{
  get
  {
    System1ConfigDataContext dc = new System1ConfigDataContext();
    return from link in this.ChildLinks
      join segment in dc.Segments on new { Site = link.ChildSite, ID = link.ChildSID } equals new { Site = segment.site, ID = segment.id }
      select segment;
  }
}

其余部分是数据绑定和数据模板,以将每个 Segment 显示为一组 UI 控件。

我很确定孩子正在按响应时间按需加载(当我扩展父级时)。当我扩展一个包含大约70个子节点的节点时,加载子节点需要一段时间(任务管理器显示 Mem Usage 为 1000000K!)。如果我用大约 50 个子节点扩展下一个节点,BOOM!内存不足异常

我运行 VS Profiler 进行更深入的挖掘,结果如下

摘要页面 对象生命周期 分配

前 3 名是 Action、DeferredSourceFactory.DeferredSource 和 EntitySet(所有 .Net/LINQ 类)。唯一的用户类是 Segment[] 和 Segment 在 #9 和 #10。

我想不出要追求的线索.. 可能是什么原因?

4

4 回答 4

1

也许是围绕那个 DataContext 的使用?

using(System1ConfigDataContext dc = new System1ConfigDataContext()){
  .... ?
}

另外,您是否尝试过使用sql profiler?可能会对此事有所启发。

于 2009-01-09T07:40:42.363 回答
0

您是否尝试过为每个元素使用全局 DataContext 而不是一个?

使用自己的查询和结果创建所有 DataContext 可能是导致内存膨胀的原因。

于 2009-01-08T21:37:19.557 回答
0

我不知道确切的解决方案,但 join 中的新语句可能会导致这种情况。因为对于每个关系都可以创建一个新对象(但正如我所提到的,我不知道它是否正确)。

你能试试这个吗?

public IEnumerable<Segment> Children
{
  get
  {
    System1ConfigDataContext dc = new System1ConfigDataContext();
    return from link in this.ChildLinks
      join segment in dc.Segments on link.ChildSite == segment.site && link.ChildSID == segment.id
      select segment;
  }
}
于 2009-01-09T07:34:42.750 回答
0

问题似乎是 Sirocco 提到的多个 S1DataContext 对象创建。我尝试了 using 语句来强制 Dispose 并使其符合收集条件。但是,它导致了我无法理解的 ObjectDisposedException。

  1. 该控件来自设置 DockPanel KeeperOfAllControls 的数据上下文的行。
  2. [外部代码](显示在调用堆栈中)
  3. Segment.Children.get(有一个带 dc 的 using 块)
  4. 回到步骤 1 中的行... ObjectDisposedExceptionLinq 查询使用从 S1DataContext 的本地实例检索的 tblSegments

无论如何,所以我假设有一些东西阻止创建和处置多个 DataContexts。所以我尝试了 Singleton DataContext
它有效!

  • TreeView 控件的响应速度明显更快,我尝试的每个节点最多在 3-4 秒内加载。
  • 我在每次获取/搜索之前放入了一个 GC.Collect(用于验证),现在内存使用量保持在 200,000-300,000K 之间。

OR 生成的 System.Data.Linq.DataContext 似乎不会消失,除非它被显式处理(吃内存)。尝试在我的情况下处理它,并没有成功..即使两个函数都有自己的 using 块(没有 DataContext 的共享实例)。虽然我不喜欢 Singletons,但我正在为开发人员制作一个小型内部工具,因此现在不介意它。我在网上看到的 LinqToSql 示例都没有强制要求 Dispose 调用。

所以我想问题已经解决了。感谢所有充当更多眼球以使这个错误变浅的人。

于 2009-01-09T10:51:48.657 回答