Dav*_*huu 1 .net c# wpf garbage-collection
我有以下XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Name="lblTime" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
代码隐藏是:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
GC.Collect();
}
void timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToLongTimeString();
GC.Collect();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道的一些事实:
在代码隐藏中,MainWindow不保留对计时器的任何引用.在我看来,它应该被销毁,界面不应该再更新,因为我放了一些GC.Collect调用.但它似乎不起作用,因为接口仍在更新,因此,对象仍然存在.
问题是:发生了什么?我错了吗?还是我错过了一些重要的事实?
编辑1:这段代码实际上是我在教程中找到的一个例子,展示了如何使用DispatcherTimer.但是我想知道当垃圾收集开始时会发生什么,这就是为什么我添加那些GC.Collect以便看看会发生什么.感谢我读过的关于.NET GC的大量教程,我知道调用GC.Collect是一个坏主意,除非非常特殊,否则不应该这样做.
Dispatcher类维护List<DispatcherTimer>活动计时器的内部.内部Dispatcher.AddTimer()方法添加它,在Start()方法上调用.RemoveTimer()由Stop()方法调用.
这使GC保持参考,直到你停止计时器.您只能通过转换发送者参数在事件处理程序中执行此操作,只能自行获取引用.
请记住,如果不调用Stop(),它会继续滴答作响,即使关闭了具有计时器事件处理程序的Window也是如此.如果你不这样做,这样的窗口对象就会泄漏,只有你很幸运,你才会得到一个ObjectDisposedException.