Friday, March 31, 2017

Garbage collection of C# timers

Can you guess the output of the following WPF code?
<Window x:Class="WpfApplication4.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">
    <TextBlock x:Name="Log" />
</Window>
using System;
using System.Threading;
using System.Windows.Threading;

namespace WpfApplication4
{
    partial class MainWindow
    {
        Timer m_timer;

        public MainWindow()
        {
            InitializeComponent();
            StartSystemThreadingTimer(1000);
            m_timer = StartSystemThreadingTimer(2000);
            StartDispatcherTimer(3000);
            GC.Collect();
        }

        void StartDispatcherTimer(int dueMilliseconds)
        {
            EventHandler callback = (sender, args) =>
            {
                Log.Text +=
                    $"DispatcherTimer {dueMilliseconds} " +
                    $"ticked at {DateTime.Now}{Environment.NewLine}";
            };
            new DispatcherTimer(TimeSpan.FromMilliseconds(dueMilliseconds),
                DispatcherPriority.Normal, callback, Dispatcher);
        }

        Timer StartSystemThreadingTimer(int dueMilliseconds)
        {
            Action doLog = () =>
            {
                Log.Text +=
                    $"System.Threading.Timer {dueMilliseconds} " +
                    $"ticked at {DateTime.Now}{Environment.NewLine}";
            };

            TimerCallback timerCallback = (sender) =>
            {
                Dispatcher.BeginInvoke(doLog);
            };

            return new Timer(timerCallback, null, dueMilliseconds, Timeout.Infinite);
        }
    }
}
The unreferenced System.Threading.Timer will be garbage collected, so the output is:
System.Threading.Timer 2000 ticked at 3/31/2017 11:19:11 PM
DispatcherTimer 3000 ticked at 3/31/2017 11:19:12 PM
DispatcherTimer 3000 ticked at 3/31/2017 11:19:15 PM
DispatcherTimer 3000 ticked at 3/31/2017 11:19:18 PM
...

No comments:

Post a Comment