绑定刷机导致内存泄漏?
假设我的应用程序中有以下课程。
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public SolidColorBrush Brush { get; set; }
public MainWindow()
{
InitializeComponent();
Brush = new SolidColorBrush(Colors.AliceBlue);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 window = new Window1();
window.DataContext = this;
window.ShowDialog();
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)delegate
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
}
MainWindow.xaml
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" >
<Button Click="Button_Click">Do It</Button>
</Window>
Window1.xaml.cs
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
~Window1()
{
Debug.WriteLine("Window1 Finalized");
}
}
Window1.xaml
<Window x:Class="WpfApplication8.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"
Background="{Binding Brush}">
<Grid>
</Grid>
</Window>
当我启动应用程序时,单击 Do It
按钮并关闭打开的窗口 - Debug.WriteLine("Window1 Finalized");
未执行。这意味着 Window1 对象仍在内存中并且未被 GC 。但是,如果我从 Window1.xaml
中删除画笔绑定 - “Window1 Finalized”字符串会出现在输出中。这意味着 Window1 对象被 GC 了。
绑定如何将对象保留在内存中?这是错误还是绑定的实现方式?
编辑1
如果我绑定Foreground 属性而不是Background 属性,则Window1 已完成。所以看来这不是依赖系统的影响,而是背景属性实现的影响。
Let's say I have following classes in my app.
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public SolidColorBrush Brush { get; set; }
public MainWindow()
{
InitializeComponent();
Brush = new SolidColorBrush(Colors.AliceBlue);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 window = new Window1();
window.DataContext = this;
window.ShowDialog();
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)delegate
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
}
MainWindow.xaml
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" >
<Button Click="Button_Click">Do It</Button>
</Window>
Window1.xaml.cs
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
~Window1()
{
Debug.WriteLine("Window1 Finalized");
}
}
Window1.xaml
<Window x:Class="WpfApplication8.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"
Background="{Binding Brush}">
<Grid>
</Grid>
</Window>
When I launch app, click Do It
button and close opened window - Debug.WriteLine("Window1 Finalized");
is not execute. This means that Window1 object is still in memory and not GCed. But if I remove brush binding from Window1.xaml
- "Window1 Finalized" string appears in output. This means that Window1 object is GCed.
How does binding keep object in memory? Is it bug or is it a way binding is implemented?
Edit 1
If I bind Foreground property instead of Background property, Window1 is finalized. So it seems it is not a Dependency system effect, but an effect of the Background property implementation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
window1 尚未最终确定,因为其 BackGround 属性中的 Binding 语法仍然引用它。
尽管绑定是 OneWay,但事实上存在到 MainWindow 属性的绑定,这意味着存在从 Mainwindow 到 Window1 的引用(由于依赖系统的工作方式) - 因此 Window1 不是垃圾收集的候选者(并且因此不会最终确定)
The window1 is not finalized because there are still references to it from the Binding syntax in its BackGround property.
Although the Binding is OneWay, the fact that there is a binding to MainWindow's Property, means there is a reference to Window1 from Mainwindow (because of the way the dependency system works) - therefore the Window1 isn't a candidate for Garbage Collection (and therefore wont be finalized)
我有类似的问题。创建后调用画笔的冻结方法解决了这个问题。
I had a similar problem. Calling the freeze method on the brush after creation resolved it.