如何在ViewModel中正确地使用Timer(定时器)
内容摘要:
这是我在某个客户那边讲课的时候遇到一个小问题,在ViewModel中创建的一个Timer,并不会被自动停止,即便使用该ViewModel的View已经被关闭了。这个问题的原因在于Timer的特殊工作机制,它是运行在一个独立的工作线程的,除非明确地停止他,或者整个程序关闭了,它才会停止。这一讲中,我通过实例重现了这个问题,然后提供了一个可行的解决方法。
视频地址:
http://HdhCmsTesttudou测试数据/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测试数据/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft测试数据/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://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于如何在ViewModel中正确地使用Timer(定时器)的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did49143