timer.Interval = 5000;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
“timer_Tick”方法是在新线程中启动还是仍然在创建它的线程中?
答案 0 :(得分:10)
不,计时器在创建计时器的线程中运行。
我假设您正在讨论使用线程消息循环实现的System.Windows.Forms.Timer
。 WinForms计时器的基础是Win32 API SetTimer()
,它通过将WM_TIMER
消息发布到SetTimer()
的线程的消息队列来运行。
其中一个后果是,如果您的事件处理程序花费的时间超过了计时器间隔,那么您的计时器将不会以所需的间隔触发。如果这是一个问题,那么你需要将你的计时器放在另一个线程中。
作为一个思想实验,想象一下如果你的计时器事件确实在不同的线程中执行会发生什么。现在您要处理同步问题。您的计时器事件可能想要访问其他线程中的对象。但这样做会导致竞争条件。
答案 1 :(得分:8)
计时器并没有真正“运行”。也就是说,当你启动一个计时器时,操作系统会创建一些数据结构,告诉它在你指定的任何时间周期性地发出“勾号”。但它并不像计时器坐在那里旋转,在等待适当时间时占用CPU资源。所有.NET计时器类型和Windows API计时器类型都以这种方式工作。
不同之处在于,当需要勾选时会发生什么。正如@David Hefferman指出的那样,使用System.Windows.Forms.Timer
,Elapsed
事件处理程序在创建计时器的同一线程上调用。 System.Threading.Timer
在线程池线程上调用它的回调。在引擎盖下,在池线程上调用System.Timers.Timer
,但您可以使用SynchronizingObject
属性在UI线程或任何其他线程上引发Elapsed
事件。