3

I have the following code for a sample console app to simulate a Windows Service.

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));

    }
}

I was surprised that the Dispose overload which accepts a WaitHandle never signals the handle when using ManualResetEventSlim. If I change the code to use a ManualResetEvent instead like so, the handle is indeed signalled.

    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));

    }
}

What gives!

Abhijeet Patel
  • 6,562
  • 8
  • 50
  • 93
  • Have you checked the return value of Dispose method? Dispose that takes wait handle returns true/false indicating success/failure. – VinayC Oct 08 '10 at 06:49
  • 1
    Regardless of the return value, Dispose should signal the handle at some point. it never does – Abhijeet Patel Oct 09 '10 at 02:32

0 Answers0