在WPF:Children.Remove或Children.Clear不免费对象 [英] In WPF: Children.Remove or Children.Clear doesn't free objects

查看:2195
本文介绍了在WPF:Children.Remove或Children.Clear不免费对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新的:我想这对另一个更干净安装的机器。我不能在该计算机上重现此。如果我发现了什么问题的(VSStudio)组件导致此,我会让你知道。

创建从后面code一些UI元素,并期待垃圾收集清理的东西。但是,对象不是自由编辑在我预期的时间。我期待他们能够在RemoveAt(0)被freeed,但他们只释放在节目的最后。

如何使从画布的孩子集合中删除当对象被释放?

 <窗​​口x:类=WpfApplication1.MainWindow
的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
标题=窗口1高度=300宽度=300
    的MouseDown =Window_MouseDown>
  <电网>
    <帆布X:名称=主/>
  < /网格>
< /窗>
 

在code的背后是:

 公共部分类主窗口:窗口
{
  公共主窗口()
  {
    的InitializeComponent();
  }

私人无效Window_MouseDown(对象发件人,MouseButtonEventArgs E)
{
  所以GC.Collect(); //这个应该拿起在previous的MouseDown删除控制
  GC.WaitForPendingFinalizers(); //也没有帮助

  如果(main.Children.Count == 0)
    main.Children.Add(新MyControl(){背景= Brushes.Yellow,宽度= 100,高度= 50});
  其他
    main.Children.RemoveAt(0);
 }
}

公共类MyControl:用户控件
{
  〜MyControl()
  {
    的Debug.WriteLine(再见);
  }
}
 

解决方案

修改

公共类MyControl:用户控件

公共类MyControl:ContentControl中

和它说再见(第二次删除控制后)我也验证了内存不使用泄漏

的Debug.WriteLine(MEM:+ GC.GetTotalMemory(真)的ToString());

此外,请参阅<一href="https://connect.microsoft.com/VisualStudio/feedback/details/424370/memory-leaks-when-using-binding">this:

  

您通过清除grid.Children删除系统testControl,但它不是立即进行垃圾回收。它几个异步操作挂起,并且它不能被GC'd直到这些操作完成(这些包括提高空载事件和一些清理code在渲染引擎)。

     

我核实,如果等到这些操作完成(比如通过安排在ContextIdle优先级的调度运行),该系统testControl就符合GC,独立的presence具有约束力的文本块。

用户控件必须具有一个内部事件,不迅速清理,也可能是用VS2010 RC的错误。我想通过连接该报告,但现在改用ContentControl中。

由于您使用的用户控件,我想你也必须切换到使用Generic.xaml模板。这是不是太困难的一个转换的(对于大多数事情是一个更好的解决方案。)

Update: I tried this on another, more cleanly installed, machine. I could not reproduce this on that machine. If I find out what offending (VSStudio) component causes this, I will let you know.

I create some UIElements from code behind and was anticipating the garbage collection to clear up stuff. However, the objects are not free-ed at the time I expected it. I was expecting them to be freeed at RemoveAt(0), but they are only freed at the end of the program.

How can I make the objects be freed when removed from the Children collection of the Canvas?

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
    MouseDown="Window_MouseDown">
  <Grid>
    <Canvas x:Name="main" />
  </Grid>
</Window>

The code behind is:

public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
  }

private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
  GC.Collect(); // This should pick up the control removed at a previous MouseDown
  GC.WaitForPendingFinalizers(); // Doesn't help either

  if (main.Children.Count == 0)
    main.Children.Add(new MyControl() { Background = Brushes.Yellow, Width = 100, Height = 50 });
  else
    main.Children.RemoveAt(0);
 }
}

public class MyControl : UserControl
{
  ~MyControl()
  {
    Debug.WriteLine("Goodbye");
  }
}

解决方案

Change

public class MyControl : UserControl

to

public class MyControl : ContentControl

and it will say goodbye (after the second time you remove the control.) I also verified the memory does not leak by using

Debug.WriteLine("mem: " + GC.GetTotalMemory(true).ToString());

Also, see this:

You remove the TestControl by clearing grid.Children, but it is not immediately eligible for garbage collection. Several asynchronous operations on it are pending, and it cannot be GC'd until those operations complete (these include raising the Unloaded event and some cleanup code in the rendering engine).

I verified that if you wait until these operations complete (say by scheduling a Dispatcher operation at ContextIdle priority), the TestControl becomes eligible for GC, independent of the presence of a binding on the TextBlock.

UserControl must either have a internal event that doesn't clean up quickly, or it might be a bug with VS2010 RC. I'd report this through connect, but for now switch to ContentControl.

Since you're using UserControl, I assume you'll also have to switch to using the Generic.xaml template. That isn't too difficult of a change-over (and for most things is a better solution.)

这篇关于在WPF:Children.Remove或Children.Clear不免费对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆