正确清理计时器和事件注册,以免引起内存泄漏

一、计时器的清理
下面的代码没有正确清理计时器。
MainWindow类使用Foo类中的计时器,在MainWindow类中将Foo实例置为null,而没有调用计时器的关闭方法,这样会导致foo对象不能被垃圾回收,只有调用计时器的关闭方法后,Foo对象才能被垃圾回收。计时器Timer可以使用Dispose方法。

Foo类

using System;
using System.Windows.Threading;

namespace DispatcherExp
{
    public class Foo
    {
        DispatcherTimer timer;
        public Foo()
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(2);
            timer.Tick += timer_Tick;
            timer.Start();
        }

        public void Dispose()
        {
            timer.Stop();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            string a = System.DateTime.Now.ToString();
        }
    }
}

MainWindow类

using System.Windows;

namespace DispatcherExp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Foo foo;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            foo = new Foo();
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            foo = null;
        }
    }
}

只需修改Button_Click_2的代码,如下所示:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
     foo.Dispose();
     foo = null;
}

二、事件的清理
MainWindow类注册NoticeWindow窗体类中的NoticeWindowClose事件,接着打开NoticeWindow窗体,窗体打开后将窗体对象置为null,接着触发NoticeWindowClose事件,发现NoticeWindowClose事件仍然能被触发,而包含事件的窗体对象将不会被垃圾回收。要想事件不被触发,应该使用代码nw.NoticeWindowClose -= nw_NoticeWindowClose注销事件的注册(见示例代码中的注释代码)。所以在使用事件时,当事件不再被使用要记得注销事件的注册,否则会使包含事件的对象不能被垃圾回收。

NoticeWindow窗体类

using System.Windows;

namespace CleanEventer
{
    /// <summary>
    /// NoticeWindow.xaml 的交互逻辑
    /// </summary>
    public partial class NoticeWindow : Window
    {
        public delegate void NoticeWindowCloseHandler();
        public event NoticeWindowCloseHandler NoticeWindowClose;

        public NoticeWindow()
        {
            InitializeComponent();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            this.Close();
            OnMessageClose();
        }

        private void OnMessageClose()
        {
            if (NoticeWindowClose != null)
            {
                NoticeWindowClose();
            }
        }
    }
}

MainWindow类

using System.Windows;

namespace CleanEventer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        NoticeWindow nw;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            nw = new NoticeWindow();
            nw.NoticeWindowClose -= nw_NoticeWindowClose;
            nw.NoticeWindowClose += nw_NoticeWindowClose;
            nw.Show();
            //nw.NoticeWindowClose -= nw_NoticeWindowClose;
            nw = null;            
        }

        void nw_NoticeWindowClose()
        {
            MessageBox.Show("Notice Window is Closing!");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值