WPF Timer与DispatcherTimer

    在vm层去渲染view层数据时,子线程直接操作UI线程(主线程),会报一个错误:调用线程无法访问此对象,因为另一个线程拥有该对象

    WPF Timer与DispatcherTimer

    1.使用System.Threading.Timer

在网上查了一下,this.Invoke()可以解决,这里以实现一个倒计时为例子:

    <Label Content="{Binding TIME}" HorizontalAlignment="Left" Margin="346,10,0,0" VerticalAlignment="Top" />


    private System.Threading.Timer t;    

    public PageViewModel()

        {
            reduce();

        }

    private void reduce()
        {
            t= new System.Threading.Timer(p=>caculateTime(),null, 0, 1000);
        }

    private void caculateTime()
        {
            if (this.TIME > 0)
                this.TIME--;
            else
            {
                this.t.Dispose();
                MainWindowsViewModel.getMWV().mf.Dispatcher.Invoke(new Action(() =>
                {
                    MainWindowsViewModel.getMWV().mf.Navigate(new Uri("page1.xaml", UriKind.Relative));
                }));
            }
        }

在caculateTime中,倒计时结束跳转页面,MainWindowsViewModel为我自己封装好的一个单例对象


2.使用DispatcherTimer

        private DispatcherTimer timer;

    

        public PageViewModel()

        {
            reduce();

        }

        private void reduce()
        {
            timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();

        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (this.TIME > 0)
                this.TIME--;
            else
            {
                this.timer.Stop();
                MainWindowsViewModel.getMWV().setFrame("page1.xaml");
            }
        }

    倒计时结束关闭子线程,跳转页面

区别在于:

DispatcherTimer是在界面线程中实现,所以可以安全的访问和修改界面的内容;但是DispatcherTimer里面执行的时间过长可能会导致UI假死。

项目GitHub地址:https://github.com/forfcw/.Net/tree/master/WPFTest