Roy*_*mir 7 c# multithreading timer .net-4.0
我在里希特的书上看到了这段代码:
下面的代码演示了如何让线程池线程调用立即启动的方法,然后每隔2秒调用一次:
/*1*/ internal static class TimerDemo
/*2*/ {
/*3*/ private static Timer s_timer;
/*4*/ public static void Main()
/*5*/ {
/*6*/ Console.WriteLine("Checking status every 2 seconds");
/*7*/ // Create the Timer ensuring that it never fires. This ensures that
/*8*/ // s_timer refers to it BEFORE Status is invoked by a thread pool thread
/*9*/ s_timer = new Timer(Status, null, Timeout.Infinite, Timeout.Infinite);
/*10*/ // Now that s_timer is assigned to, we can let the timer fire knowing
/*11*/ // that calling Change in Status will not throw a NullReferenceException
/*12*/ s_timer.Change(0, Timeout.Infinite);
/*13*/ Console.ReadLine(); // Prevent the process from terminating
/*14*/ }
/*15*/ // This method's signature must match the TimerCallback delegate
/*16*/ private static void Status(Object state)
/*17*/ {
/*18*/ // This method is executed by a thread pool thread
/*20*/ Console.WriteLine("In Status at {0}", DateTime.Now);
/*21*/ Thread.Sleep(1000); // Simulates other work (1 second)
/*22*/ // Just before returning, have the Timer fire again in 2 seconds
/*23*/ s_timer.Change(2000, Timeout.Infinite);
/*24*/ // When this method returns, the thread goes back
/*25*/ // to the pool and waits for another work item
/*26*/ }
/*27*/ }
Run Code Online (Sandbox Code Playgroud)
但是,(对不起),我还是不明白什么行#7,#8意味着什么
当然 - 为什么它被初始化(第9行)Timeout.Infinite(很明显:" 不要启动计时器 ")
(我确实理解防止重叠的一般目的,但我相信这里也存在GC竞争条件.)
命名空间是 System.Threading
Pra*_*eek 11
我认为这与GC没有关系,而是为了避免竞争条件:
赋值操作不是原子操作:首先创建Timer对象然后分配它.
所以这是一个场景:
new Timer(...) 创建计时器,它开始"计数"
在赋值结束之前,当前线程被抢占 => s_timer仍为空
该计时器唤醒另一个线程和调用Status,但最初的线程尚未完成赋值操作!
Status访问s_timer哪个是空引用 => BOOM!
使用他的方法不可能发生,例如使用相同的场景:
计时器已创建但未启动
当前线程被抢占
没有任何反应,因为计时器尚未开始引发事件
初始线程再次运行
它结束赋值 => s_timer 引用计时器
计时器安全启动:任何将来的调用Status都是有效的,因为它s_timer是一个有效的引用