A colleague of mine found what seems to be a bug in Silverlight 4. Once started, DispatcherTimer object is never garbage collected. The following code snippet demonstrates the issue:
public partial class MainPage : UserControl {
public MainPage() {
InitializeComponent();
}
private void start_Click(object sender, RoutedEventArgs e) {
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e) {
DispatcherTimer timer = (DispatcherTimer)sender;
timer.Stop();
timer.Tick -= timer_Tick;
}
}
0:028> !dumpheap -type DispatcherTimer
Address MT Size
total 0 objects
Statistics:
MT Count TotalSize Class Name
Total 0 objects
Then click “Start” button. Wait a couple of seconds – the timer object fires, stops and unsubscribes from event handler. Now break into the debugger once again:
0:003> !dumpheap -type DispatcherTimer
Address MT Size
08ff5df8 629c4ba0 20
total 0 objects
Statistics:
MT Count TotalSize Class Name
629c4ba0 1 20 System.Windows.Threading.DispatcherTimer
Total 1 objects
0:003> !gcroot -nostacks 08ff5df8
DOMAIN(07F1AE30):HANDLE(Pinned):43b12f8:Root: 09f74260(System.Object[])->
08fa5f64(System.Collections.Generic.Dictionary`2[[System.IntPtr, mscorlib],[System.Object, mscorlib]])->
08feafc4(System.Collections.Generic.Dictionary`2+Entry[[System.IntPtr, mscorlib],[System.Object, mscorlib]][])->
08ff5df8(System.Windows.Threading.DispatcherTimer)
As you can see, the timer object is “rooted” in Dictionary entry and it will prevent it from being garbage collected.
Комментариев нет:
Отправить комментарий