zoukankan      html  css  js  c++  java
  • 如何在ViewModel中正确地使用Timer(定时器)

    内容摘要:

    这是我在某个客户那边讲课的时候遇到一个小问题,在ViewModel中创建的一个Timer,并不会被自动停止,即便使用该ViewModel的View已经被关闭了。这个问题的原因在于Timer的特殊工作机制,它是运行在一个独立的工作线程的,除非明确地停止他,或者整个程序关闭了,它才会停止。这一讲中,我通过实例重现了这个问题,然后提供了一个可行的解决方法。

    视频地址:

    http://www.tudou.com/programs/view/uO4b2j0N4L8/

    示例代码:

    备注:该范例使用了MvvmLight作为MVVM框架,请自行安装

    Model:

    using System;
    using System.Diagnostics;
    using System.Linq;
    
    namespace SilverlightApplicationSample
    {
        public class DataService
        {
            public static Customer[] GetCustomers()
            {
    
                Debug.WriteLine(string.Format("[{0}]正在调用数据服务",DateTime.Now));
    
                var rnd = new Random();
                return Enumerable.Range(1, rnd.Next(100)).Select(x => new Customer()
                {
                    CompanyName = "Company " + x.ToString()
                }).ToArray();
    
            }
        }
    
        public class Customer
        {
            public string CompanyName { get; set; }
        }
    }
    
     
    ViewModel:
    using System;
    using System.Windows.Threading;
    using GalaSoft.MvvmLight;
    
    namespace SilverlightApplicationSample
    {
        /// <summary>
        /// 使用MVVMLight实现的MVVM ViewModel
        /// </summary>
        public class CustomerWindowViewModel : ViewModelBase
        {
            /// <summary>
            /// 这个方法也不会自动调用
            /// </summary>
            public override void Cleanup()
            {
                base.Cleanup();
    
                timer.Stop();
            }
    
     
    
            DispatcherTimer timer = null;
    
            public CustomerWindowViewModel()
            {
                //正常情况下的绑定
                //Customers = DataService.GetCustomers();
    
    
                //使用定时器调用服务
                timer = new DispatcherTimer();
    
                timer.Interval = TimeSpan.FromSeconds(1);
                timer.Tick += (o, a) =>
                {
                    Customers = DataService.GetCustomers();
                };
    
                timer.Start();
            }
    
            private Customer[] _Customers;
            public Customer[] Customers
            {
                get { return _Customers; }
                set
                {
                    if (_Customers != value)
                    {
                        _Customers = value;
                        RaisePropertyChanged("Customers");
                    }
                }
            }
        }
    }
    

    View:

    <controls:ChildWindow x:Class="SilverlightApplicationSample.CustomerWindow"
                          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                          xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
                          Width="400"
                          Height="300"
                          Title="CustomerWindow"
                          xmlns:local="clr-namespace:SilverlightApplicationSample">
        <controls:ChildWindow.DataContext>
            <local:CustomerWindowViewModel></local:CustomerWindowViewModel>
        </controls:ChildWindow.DataContext>
        
        <Grid x:Name="LayoutRoot"
              Margin="2">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
    
    
            <ListBox ItemsSource="{Binding Customers}"
                     DisplayMemberPath="CompanyName">
            </ListBox>
    
            <Button x:Name="CancelButton"
                    Content="Cancel"
                    Click="CancelButton_Click"
                    Width="75"
                    Height="23"
                    HorizontalAlignment="Right"
                    Margin="0,12,0,0"
                    Grid.Row="1" />
            <Button x:Name="OKButton"
                    Content="OK"
                    Click="OKButton_Click"
                    Width="75"
                    Height="23"
                    HorizontalAlignment="Right"
                    Margin="0,12,79,0"
                    Grid.Row="1" />
        </Grid>
    </controls:ChildWindow>
     
     
    Page:
    using System.Windows;
    using System.Windows.Controls;
    
    namespace SilverlightApplicationSample
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var window = new CustomerWindow();
                window.Closed += (o, a) =>
                {
                    var vm = window.DataContext as CustomerWindowViewModel;
                    vm.Cleanup();
                };
    
                window.Show();
            }
        }
    }
    
  • 相关阅读:
    蛇形填数
    A Famous Music Composer
    Java用筛子法求素数
    素数求和问题
    Java中数组的快排
    大数阶乘
    Binary String Matching
    括号配对问题
    Android Studio安装和使用
    Android Studio使用手册
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2485045.html
Copyright © 2011-2022 走看看