rem*_*rem 25 .net wpf multithreading timer
请解释@Dent Boogaart在多线程WPF应用程序中使用的"DispatcherTimer"和"常规计时器"之间的区别,作为本主题中的任务参与者:
在其中一篇帖子的评论中(引用):
- 如果所有DispatcherTimer都启动另一个线程,那么使用DispatcherTimer有什么意义呢?....那些线程不需要在UI线程上启动.您可以使用常规Timer,避免完全中断UI
什么是"常规计时器"?他们("DispatcherTimer"和"常规计时器")对UI的影响有何不同?
(在阅读这篇文章之前,我认为DispatcherTimer是在WPF中使用计时器的一种自然方式.当这不是真的时候会是什么情况?)
Han*_*ant 43
DispatcherTimer是常规计时器.它在UI线程上触发其Tick事件,您可以使用UI执行任何操作.System.Timers.Timer是一个异步计时器,其Elapsed事件在线程池线程上运行.您必须在事件处理程序中非常小心,不允许您触摸任何UI组件或数据绑定变量.并且您将需要使用lock语句,只要您访问也在UI线程上使用的类成员.
在链接的答案中,Timer类更合适,因为OP试图故意异步运行代码.
Aka*_*ava 31
常规计时器的Tick事件实际上是在创建Timer的线程上触发的,因此在tick事件中,为了使用UI访问任何内容,您将必须通过dispatcher.begininvoke,如下所述.
RegularTimer_Tick(object sender, EventArgs e)
{
txtBox1.Text = "count" + i.ToString();
// error can not access
// txtBox1.Text property outside dispatcher thread...
// instead you have to write...
Dispatcher.BeginInvoke( (Action)delegate(){
txtBox1.Text = "count " + i.ToString();
});
}
Run Code Online (Sandbox Code Playgroud)
在Dispatcher Timer的情况下,您可以访问UI元素而无需开始调用或调用如下...
DispatcherTimer_Tick(object sender, EventArgs e)
{
txtBox1.Text = "Count " + i.ToString();
// no error here..
}
Run Code Online (Sandbox Code Playgroud)
DispatcherTimer提供了方便的常规计时器,可以轻松访问UI对象.
Sim*_*ver 16
使用.NET 4.5,async如果需要使用新的.NET 4.5 await功能,还可以为计时器创建委托.
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(20);
timer.Tick += new EventHandler(async (object s, EventArgs a) =>
{
Message = "Updating...";
await UpdateSystemStatus(false);
Message = "Last updated " + DateTime.Now;
});
timer.Start();
Run Code Online (Sandbox Code Playgroud)