DispatcherTimer仍在Stop()之后勾选事件并设置为null

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DispatcherTimer仍在Stop()之后勾选事件并设置为null相关的知识,希望对你有一定的参考价值。

我正在写一个应用程序来听音乐和观看视频。在应用程序中,我有这两个页面:1播放音频播放代理(APA) - 页面A,一个播放视频(使用MediaElement) - 页面B.虽然WP8有APA的错误(我已经在这里问here (我找到了一个解决方案 - 在MediaElement播放和关闭之前和之后两次停止APA)。

问题是,在A页面上,我每秒使用DispatcherTimer滴答来检查APA实例位置,当我离开此页面时,我有一个功能来停止此DispatcherTimer。

即使如此,如果我多次导航到页面A和从页面A导航,然后导航到页面B,1秒后应用程序在if (BackgroundAudioPlayer.Instance.PlayerState == ...处抛出异常。这意味着DispatcherTimer仍然会勾选?????我该怎么强行阻止这个:(


我在这里发布了与DispatcherTimer相关的所有代码:

public DetailSongPage()
    {
        InitializeComponent();
        this.DataContext = App.Model;            
        BackgroundAudioPlayer.Instance.PlayStateChanged += APA_Instance_PlayStateChanged;                        
    }
DispatcherTimer timer = null;

private void APA_Instance_PlayStateChanged(object sender, EventArgs e)
    {
        if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
        {                
            UpdateTracking();
        }              
    }
protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);                           
        if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing || BackgroundAudioPlayer.Instance.PlayerState == PlayState.Paused)
        {   
            UpdateTracking();   
        }
    }
protected override void OnNavigatedFrom(NavigationEventArgs e)
    { 
        base.OnNavigatedFrom(e);
        timer.Stop();            
        timer.Tick -= timer_Tick;
        timer = null;            
    }
private void UpdateTracking()
    {
        sldTracking.Maximum = BackgroundAudioPlayer.Instance.Track.Duration.TotalMilliseconds;
        tbMaxTime.Text = string.Format(@"{0:mm:ss}",BackgroundAudioPlayer.Instance.Track.Duration);
        // ^ these 2 lines update the UI for the slider and textblock 

        if (timer == null)
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(1000);
            timer.Tick += timer_Tick;
            timer.Start();
        }  
    }
    private void timer_Tick(object sender, EventArgs e)
    {
        if (this.timer != null)
        {
            try
            {                   
                if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing || BackgroundAudioPlayer.Instance.PlayerState == PlayState.Paused)
                {
                    sldTracking.Value = BackgroundAudioPlayer.Instance.Position.TotalMilliseconds;
                    tbCurrentTime.Text = string.Format(@"{0:mm:ss}", BackgroundAudioPlayer.Instance.Position);
                }
            }
            catch
            {
                return;
            }
        }
    }
答案

你可以在你的类中实现IDispose,在这个实现中,停止计时器。然后在离开页面时调用Dispose。在Dispose中,你应该写下这样的东西:

timer?.Stop();

以上是关于DispatcherTimer仍在Stop()之后勾选事件并设置为null的主要内容,如果未能解决你的问题,请参考以下文章

Timer和DispatcherTimer简单使用

浅谈(WPF)DispatcherTimer

比较 Timer 和 DispatcherTimer

WPF 如何知道当前有多少个 DispatcherTimer 在运行

如何重置DispatcherTimer?

无法创建 DispatcherTimer [重复]