System.OutOfMemoryException 与 observablecollection

System.OutOfMemoryException with observablecollection

我正在使用绑定到 dataGrid 的可观察集合来使用所选客户的库存刷新网格。

我正在遍历返回的集合并使用 foreach 循环,以便 UI 了解新项目。

请注意,我将这段代码放在按钮下只是为了测试,并确保我没有进行一些时髦的重入操作。

            // Grab the customer ID 
            int customerID = ((Customer)cboCustomer.SelectedItem).Customer_ID;

            ocInventoryItems.Clear();
            ObservableCollection<InventoryItem> ocTemp = Inventory.RetrieveObservableCollection(customerID);
            foreach (InventoryItem item in ocTemp)
            {
                ocInventoryItems.Add(item);
            }

网格的 XAML 在这里:

ItemsSource="{Binding ocInventoryItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"    

库存返回并分配给 ocInventoryItems observablecollection 后,出现内存不足异常。

我已经阅读了关于对象的 2Gig 限制,但我认为我没有达到这个限制。
据我所知,将集合加载到之后的增加量仅为 6 兆左右。 (使用 GC.GetTotalMemory(真);)

库存搜索屏幕上也使用了相同的查询和集合。该屏幕 returns 所有库存都没有问题。

我还阅读了有关 observablecollections 的潜在内存泄漏的信息,因此我尝试进行绑定 "OneWay" 和 "OneTime"。还是不开心。

我已经对 InventoryItem class 的所有非只读属性实施了 iNotofiyPropertyChanged。 (我读过没有它会导致 OC 内存泄漏)

这似乎是一个真正的内存不足错误,当我选择一个库存较少的客户时,我就成功了。

这让我相信某个地方的内存没有被正确释放或者存在泄漏......

我只是不知道在哪里。我确实将此 运行 作为一项任务,但现在将其删除,直到我可以找到问题为止。

堆栈跟踪:

Stack Trace:    at System.Windows.Media.Composition.DUCE.Channel.CreateOrAddRefOnChannel(Object instance, ResourceHandle& handle, ResourceType resourceType)
   at System.Windows.Media.Composition.VisualProxy.CreateOrAddRefOnChannel(Object instance, Channel channel, ResourceType resourceType)
   at System.Windows.Media.Visual.AddRefOnChannelCore(Channel channel)
   at System.Windows.Media.Visual.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(Channel channel)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.Render(RenderContext ctx, UInt32 childIndex)
   at System.Windows.Media.CompositionTarget.Compile(Channel channel)
   at System.Windows.Media.CompositionTarget.System.Windows.Media.ICompositionTarget.Render(Boolean inResize, Channel channel)
   at System.Windows.Media.MediaContext.Render(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate zzzzzzz

可能不是解决方法,但为什么是 ocTemp
一开始

ocInventoryItems.Clear();
foreach (InventoryItem item in Inventory.RetrieveEnemerable(customerID))
{
    ocInventoryItems.Add(item);
}

验证 InventoryItem 没有任何订阅在尝试处理操作期间将其固定到内存。

简答:这是一个 "redraw" 类的问题。当我将网格布局调整到屏幕上的不同位置时 - 没有问题并且加载速度很快。

长答案(我是怎么得到这个的):我试过稍微移动数据网格但无济于事,所以我最初放弃了这个。这是我完成的步骤的快速列表。

1) 将数据网格和加载代码放在一个干净的 window 中。完美运行。

2) 将数据网格和加载代码放在一个干净的用户控件中,该控件继承自我常用的 ucBase。完美运行。

3) 回到原来的用户控件,注释掉一个正在工作的数据网格并将 "bad" 放在它的位置。工作完美。

之后我知道问题与布局和重绘有关。我只是一次一步地重新组织我的布局,直到我在我想要的地方拥有两个数据网格并且没有内存错误。抱歉,我不能说得更具体,但它的布局很复杂,有多个网格拆分器、数据网格等。

我的理论: 我猜我的控件布局不当,导致每次向可观察的集合

相关问题:我以前见过这个问题,当时滚动查看器中的网格不知何故导致代码锁定。我应该猜到这些问题是相似的。

希望这对某人有所帮助。一个简单的修复是一条漫长的道路。

更新:

我今晚偶然发现了一些更清晰的内容。如果 dataGrid 在网格行内并且行高度为 "Auto" 并且您正在将许多项目添加到数据网格绑定到的集合中(在我的例子中超过 9,000)... wpf 会因为你的记忆而疯狂它会在每次添加到集合后尝试调整大小。像“1*”这样简单的星星高度会让一切都开心。