代码之家  ›  专栏  ›  技术社区  ›  Abhijeet Patel

System.Threading.Timer的Dispose方法不适用于ManualResetEventSlim?

  •  2
  • Abhijeet Patel  · 技术社区  · 14 年前

    下面是一个示例控制台应用程序的代码,用于模拟Windows服务。

    class Program
    {
        private Timer timer;
        private object syncRoot = new object();
        private bool stopSignalled = false;
        private ManualResetEventSlim mre = new ManualResetEventSlim(false);
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Start();
            Console.ReadLine();
            p.Stop();
            Console.WriteLine("Stopped at:{0:G}", DateTime.Now);
        }
    
        private void Stop()
        {
            stopSignalled = true;
            mre.Wait();            
    
        }
        private void Timercallback(object state)
        {
            lock (syncRoot)
            {
                if (!stopSignalled)
                {
                     Console.WriteLine("Callback invoked  at:{0:G}",DateTime.Now);
    
                }
                else
                {
                    timer.Dispose(mre.WaitHandle);
                    Console.WriteLine("Timer disposed at:{0:G}", DateTime.Now);
                }
            }
    
        }
    
        private void Start()
        {
            Console.WriteLine("Started at:{0:G}",DateTime.Now);
            timer = new Timer(Timercallback,null,TimeSpan.Zero,TimeSpan.FromSeconds(1));
    
        }
    }
    

    我很惊讶,接受WaitHandle的Dispose重载在使用ManualResetEventSlim时从未向句柄发出信号。 如果我将代码改为像这样使用ManualResetEvent,那么句柄确实是有信号的。

        class Program
    {
        private Timer timer;
        private object syncRoot = new object();
        private bool stopSignalled = false;
        private ManualResetEvent mre = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Start();
            Console.ReadLine();
            p.Stop();
            Console.WriteLine("Stopped at:{0:G}", DateTime.Now);
        }
    
        private void Stop()
        {
            stopSignalled = true;
            mre.WaitOne();            
    
        }
        private void Timercallback(object state)
        {
            lock (syncRoot)
            {
                if (!stopSignalled)
                {
                     Console.WriteLine("Callback invoked  at:{0:G}",DateTime.Now);
    
                }
                else
                {
                    timer.Dispose(mre);
                    Console.WriteLine("Timer disposed at:{0:G}", DateTime.Now);
                }
            }
    
        }
    
        private void Start()
        {
            Console.WriteLine("Started at:{0:G}",DateTime.Now);
            timer = new Timer(Timercallback,null,TimeSpan.Zero,TimeSpan.FromSeconds(1));
    
        }
    }
    

    0 回复  |  直到 14 年前