2011-04-17 64 views
18

我有一个主线程创建一个表单对象,它创建并设置一个计时器,每分钟运行一个名为updateStatus()的函数。但updateStatus()也被几个地方的主线程调用。System.Windows.Forms.Timer是否在与UI不同的线程上运行?

但是,我不清楚它是否会导致任何同步问题。 C#中的System.Windows.Forms.Timer是否在除主线程以外的其他线程上运行?

回答

20

不,计时器事件在UI线程上引发。

您不会有任何同步问题。这是在WinForms应用程序中使用的定时器控件的正确版本;它是专门设计来完成你所要求的。它使用标准Windows timer在引擎盖下实施。

documentation证实了这一点在备注部分:

A定时器被用来提高在用户定义的时间间隔的事件。此Windows计时器专用于UI线程用于执行处理的单线程环境。它要求用户代码具有可用的UI消息泵,并始终从同一线程运行,或将该调用编组到另一个线程。

当您使用此计时器时,使用Tick事件执行轮询操作或在指定的时间段内显示启动画面。只要Enabled属性设置为true并且Interval属性大于零,则会根据Interval属性设置间隔引发Tick事件。

+0

因此,Windows定时器在主线程上运行,它将始终是同步的,我不需要将锁定块放入updateStatus()函数中。我对吗? – user186246 2011-04-18 04:41:16

+0

@user:是的,没错。它像在窗体上引发的其他事件一样运行,例如'Paint'或'Load'事件。你也不需要锁定那些处理程序。 – 2011-04-18 04:45:48

6

编号

Windows.Forms定时器的全部重点是它在GUI线程上运行。

Windows(WinForms)运行一个名为MessagePump的东西(见Application.Run()),这就是Timer的可能性。

所有代码都以某种方式作为事件处理程序的一部分运行,并且计时器滴答不会“中断”任何其他事件处理程序。

+0

嗨,Iam不知道messagePump。你能提供一些关于它的信息吗? – user186246 2011-04-18 04:44:16

+0

一些信息:http://blogs.msdn.com/b/oldnewthing/archive/2014/12/04/10577881.aspx – 2015-04-14 18:55:39

2

根据它运行在主UI线程上documentation

使用定时器在 用户定义的间隔来引发事件。此Windows 计时器专为 单线程环境而设计,其中UI 线程用于执行 处理。它要求用户 代码具有可用的UI消息泵 ,并且始终从相同的 线程操作,或将呼叫编组到另一个线程 。

4

Windows.Forms计时器在UI线程上提取事件,大概是通过sync-context。

如果你想有一个非UI线程,还有其他的计时器 - 例如System.Timers.Timer或System.Threading.Timer

+1

不完全。它使用Windows消息,所以它永远不会离开UI线程。 – SLaks 2011-04-17 15:49:44

8

否,计时器的Tick事件从UI线程的消息引发当它收到WM_TIMER消息时循环。你总是很擅长,它只能在你的UI线程空闲时运行。

相关问题