计时器是否创建新线程?

时间:2011-03-05 16:06:01

标签: c# multithreading timer

        timer.Interval = 5000;
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();

“timer_Tick”方法是在新线程中启动还是仍然在创建它的线程中?

2 个答案:

答案 0 :(得分:10)

不,计时器在创建计时器的线程中运行。

我假设您正在讨论使用线程消息循环实现的System.Windows.Forms.Timer。 WinForms计时器的基础是Win32 API SetTimer(),它通过将WM_TIMER消息发布到SetTimer()的线程的消息队列来运行。

其中一个后果是,如果您的事件处理程序花费的时间超过了计时器间隔,那么您的计时器将不会以所需的间隔触发。如果这是一个问题,那么你需要将你的计时器放在另一个线程中。

作为一个思想实验,想象一下如果你的计时器事件确实在不同的线程中执行会发生什么。现在您要处理同步问题。您的计时器事件可能想要访问其他线程中的对象。但这样做会导致竞争条件。

答案 1 :(得分:8)

计时器并没有真正“运行”。也就是说,当你启动一个计时器时,操作系统会创建一些数据结构,告诉它在你指定的任何时间周期性地发出“勾号”。但它并不像计时器坐在那里旋转,在等待适当时间时占用CPU资源。所有.NET计时器类型和Windows API计时器类型都以这种方式工作。

不同之处在于,当需要勾选时会发生什么。正如@David Hefferman指出的那样,使用System.Windows.Forms.TimerElapsed事件处理程序在创建计时器的同一线程上调用。 System.Threading.Timer在线程池线程上调用它的回调。在引擎盖下,在池线程上调用System.Timers.Timer,但您可以使用SynchronizingObject属性在UI线程或任何其他线程上引发Elapsed事件。