更新:我在另一个更干净的机器上试过这个。我无法在该机器上重现这一点。如果我发现哪些违规(VSStudio)组件会导致此问题,我会通知您。在WPF:Children.Remove或Children.Clear不会释放对象
我从后面的代码创建了一些UIElements,并期待垃圾收集来清理东西。但是,在我期待的时候,这些对象并不是免费的。我期待他们在RemoveAt(0)被释放,但他们只在程序结束时被释放。
如何从Canvas的Children集合中移除对象时如何释放对象?
<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>
后面的代码是:在C#
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");
}
}
我知道,注销已命名的类,但不这么认为在这种情况下。当我在MouseDown处理程序的开头添加GC.Collect()时,它应该选择符合垃圾收集条件的控件。它没有。我收集的内容仍然必须在Canvas对象内部引用它。 – 2010-03-29 22:47:23
@Bart:尝试在处理程序的END处添加GC.Collection - 控件仍处于处理程序开始处的UI中...是否有帮助? – 2010-03-29 22:48:32
@Bart:另外 - 尝试添加对GC.WaitForPendingFinalizers()的调用 - 请参阅:http://msdn.microsoft.com/en-us/library/system.gc.waitforpendingfinalizers.aspx – 2010-03-29 22:49:49