在wpf中使用timer Timers in WPF

本文探讨了在WPF应用程序中使用不同类型的定时器时遇到的问题及解决方案。重点介绍了如何正确使用System.Windows.Threading.DispatcherTimer来更新UI,避免跨线程访问异常。

重要更新:

09.12.10.

System.Windows.Forms.Timer 在WPF 挂接的事件函数中被激活的时候不会运行,你可以设置它开始,并且状态也会是enabled = true, 但是就是不会计数

最安全还是要用 System.Timers.Timer

关键词 Key:

Exception Information: The calling thread cannot access this object because a different thread owns it.

Use timer in WPF.

原文链接 From:

http://daneshmandi.spaces.live.com/blog/cns!2DFAE0F19A7C2F5F!246.entry

我在项目中选择的解决方案 Solution I choosen:

Use System.Windows.Threading.DispatcherTimer replace timer

原文有其他的解决方案,请自行阅读

我的用法 How to use:

DispatcherTimer timer = new DispatcherTimer(); timer.Tick += new EventHandler(timer_Tick); timer.Interval = new TimeSpan(350); void timer_Tick(object sender, EventArgs e) { if(timer.IsEnabled == true) { timer.Stop(); } }

原文 Text:

Recently I was working on a WPF app and I wanted to use a timer to do something automaticaly in the backgroundand then update something in the UI. At first I wasfaced withsome problems. But after all I found how Ishould use Timer in WPFSo I decided to post it here forthe oneswho might facewiththe sameissue.
First of all, here is the code which uses a timer to change the background color of the window with random generated color:
public partial class TimerTesting : Window

{

public TimerTesting()

{

InitializeComponent();

System.Threading.TimerCallback tc = new System.Threading.TimerCallback(this.OnTimerCallback);

System.Threading.Timer objTimer = new System.Threading.Timer(tc);

objTimer.Change(0, 500);

}

private void OnTimerCallback(Object obj)

{

Random r = new Random();

this

.Background = new SolidColorBrush(Color.FromRgb((byte)(r.Next(0, 255)), (byte)(r.Next(0, 255)), (byte)(r.Next(0, 255))));

}

}

When we wanted to set the background of the window in the Callback methodthis exception fires. "The calling thread cannot access this object because a different thread owns it.". This problem is due to UI thread in WPF is different from the thread that owns our timer. In fact, the Dispatcher object manage the UI (in this case the window). Therefore updating the UI should handle with Dispatcher object that owns it. So we should change our code in the CallBack method to this way:

private

void OnTimerCallback(Object obj)

{

this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,

(System.Threading.ThreadStart)delegate()

{

Random r = new Random();

this.Background = new SolidColorBrush(Color.FromRgb((byte)(r.Next(0, 255)), (byte)(r.Next(0, 255)), (byte)(r.Next(0, 255))));

});

}

In WPF the only thread that created the DispatcherObject mayaccess that object. Therefore we should first find the Dispatcher object of the window then tell it to update the data on the window. Moreover, The BeginInvoke method of the DispatcherObject executes the delegate asynchronously on the thread that the Dispatcher is associated with which in our code is the DispatcherObject of the window.

In the Case of Timer, we can usethree kinds of Timersin WPFwhich two of them were available beforeWPF; As we dicussed above System.Threading.Timer and System.Timers.Timer. But the third one is made especiallyfor WPF; System.Windows.Threading.DispatcherTimer. The difference between this timer with thetwo others is that it belongs to the same thread as WPF UI thread. By that I mean the DispatcherObject owns it. Better say, in the case ofour example above the thread of the window and thetimer are the same sowe can Update the UI data without anyproblem.

public

partial class TimerTesting : Window

{

public TimerTesting()

{

InitializeComponent();

System.Windows.Threading.DispatcherTimer dTimer = new System.Windows.Threading.DispatcherTimer();

dTimer.Tick += new EventHandler(dispatcherTimer_Tick);

dTimer.Interval = TimeSpan.FromMilliseconds(500);

dTimer.Start();

}

private void dispatcherTimer_Tick(object sender, EventArgs e)

{

Random r = new Random();

this.Background = new SolidColorBrush(Color.FromRgb((byte)(r.Next(0, 255)), (byte)(r.Next(0, 255)), (byte)(r.Next(0, 255))));

}

}

You can download the complete source codehere.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值