如何在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(); } } }
分类: WPF或者Silverligh , fmplan-02 - Developement Practice-02-1-Desktop
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于如何在ViewModel中正确地使用Timer(定时器)的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did49143