微软的示例:
1 using System; 2 using System.Threading; 3 namespace ConsoleTimer 4 { 5 class TimerExample 6 { 7 static void Main() 8 { 9 // Create an event to signal the timeout count threshold in the10 // timer callback.11 AutoResetEvent autoEvent = new AutoResetEvent(false);12 13 StatusChecker statusChecker = new StatusChecker(10);//14 15 // Create an inferred delegate that invokes methods for the timer.16 TimerCallback tcb = statusChecker.CheckStatus;//timer异步回调的方法17 18 // Create a timer that signals the delegate to invoke 19 // CheckStatus after one second, and every 1/4 second 20 // thereafter.21 Console.WriteLine("{0} Creating timer.\n",22 DateTime.Now.ToString("h:mm:ss.fff"));23 Timer stateTimer = new Timer(tcb, autoEvent, 1000, 250);//等待1s,时间间隔250ms
- callback
- 类型: 一个 TimerCallback 委托,表示要执行的方法。 state
- 类型: 一个包含回调方法要使用的信息的对象,或者为 null。 dueTime
- 类型: 调用 callback 之前延迟的时间量(以毫秒为单位)。 指定 Timeout.Infinite 可防止启动计时器。 指定零 (0) 可立即启动计时器。 period
- 类型: 调用 callback 的时间间隔(以毫秒为单位)。 指定 Timeout.Infinite 可以禁用定期终止。 24 25 // When autoEvent signals, change the period to every 26 // 1/2 second. 27 autoEvent.WaitOne( 5000, false );//等待5000ms,执行回调过程,到达5000ms后线程被阻止
- 28 stateTimer.Change( 0, 500 );//等待的时间间隔改为500ms 29 Console.WriteLine( " \nChanging period.\n " ); 30 31 // When autoEvent signals the second time, dispose of
- 32 // the timer. 33 autoEvent.WaitOne( 500, false ); 34 stateTimer.Dispose(); 35 Console.WriteLine( " \nDestroying timer. " ); 36 Console.ReadKey(); 37 } 38 } 39 40 class StatusChecker 41 { 42 private int invokeCount; 43 private int maxCount;//最大检查次数 44 45 public StatusChecker( int count) 46 { 47 invokeCount = 0 ; 48 maxCount = count; 49 } 50 51 // This method is called by the timer delegate. 52 public void CheckStatus(Object stateInfo) 53 { 54 AutoResetEvent autoEvent = (AutoResetEvent)stateInfo; 55 Console.WriteLine( " {0} Checking status {1,2}. " , 56 DateTime.Now.ToString( " h:mm:ss.fff " ), 57 (++ invokeCount).ToString()); 58 59 if (invokeCount == maxCount) 60 { 61 // Reset the counter and signal Main. 62 invokeCount = 0 ; 63 autoEvent.Set(); 64 } 65 } 66 67 } 68 }
使用AutoResetEvent类的示例:
1 using System; 2 using System.Threading; 3 4 class WaitOne 5 { 6 static AutoResetEvent autoEvent = new AutoResetEvent(false); 7 8 static void Main() 9 {10 Console.WriteLine("Main starting.");11 12 ThreadPool.QueueUserWorkItem(13 new WaitCallback(WorkMethod), autoEvent);14 15 // Wait for work method to signal.16 if (autoEvent.WaitOne(1000))//线程等待1000Ms后阻止,(阻止当前线程,直到当前 WaitHandle 收到信号)17 {18 Console.WriteLine("Work method signaled.");19 }20 else21 {22 Console.WriteLine("Timed out waiting for work " +23 "method to signal.");24 }25 Console.WriteLine("Main ending.");26 Console.ReadKey();27 }28 29 static void WorkMethod(object stateInfo)30 {31 Console.WriteLine("Work starting.");32 33 // Simulate time spent working.34 Thread.Sleep(new Random().Next(1000, 2000)); 35 //2.Thread.Sleep(new Random().Next(200, 1000));36 // Signal that work is finished.37 Console.WriteLine("Work ending.");38 ((AutoResetEvent)stateInfo).Set();//将事件状态设置为终止状态,允许一个或多个等待线程继续。 39 }40 }
修改绿色代码2,结果分别如下。实现了两个线程的同步。
使用过程中出现的错误,回调方法为什么执行一会就停止不运行了:
帮助里说的很清楚:只要在使用 Timer,就必须保留对它的引用。对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。即使 Timer 仍处在活动状态,也会被回收。
因为你原来声明的t是一个局部变量,当t出了作用域以后,new System.Threading.Timer(new TimerCallback(scan),null, 0, 2000);就随时会被垃圾回收,自然对话框就停止了