Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

dispose - Why do I never get the ObjectDisposedException?

My test method looks like this:

private static System.Timers.Timer _myTimer;

static void Main(string[] args)
    {
        using (_myTimer = new System.Timers.Timer(1000))
        {
            _myTimer.Elapsed += (o, e) => Console.WriteLine($"timer elapsed");
            _myTimer.AutoReset = true;
            _myTimer.Enabled = true;
            Thread.Sleep(4000); // let the timer fire a couple of times
        } // dispose timer?

        Thread.Sleep(2000); // timer won't fire here
        try
        {
            Console.WriteLine($"no problem accessing _myTimer: {_myTimer.Interval}"); // this won't throw an ObjectDisposedException on _myTimer
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex}");
        }

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        try
        {
            Console.WriteLine($"no problem accessing _myTimer: {_myTimer.Interval}"); // still no ObjectDisposedException
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex}");
        }

        try
        {
            //_myTimer.Start(); // throws the ObjectDisposedException
            _myTimer.Dispose(); // does not throw the ObjectDisposedException
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex}");
        }            

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        try
        {
            Console.WriteLine($"no problem accessing _myTimer: {_myTimer.Interval}"); // still no ObjectDisposedException
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex}");
        }

        Console.WriteLine("Press any key to continue...");
        Console.ReadLine();
    }  

I would expect to get the ObjectDisposedException after leaving the using block.

Accessing the _myTimer.Interval works all the way to the end of the program. Also, I can call _myTimer.Dispose() anytime. Even waiting for the GarbageCollector does not help to get the ObjectDisposedException.

However, I do get the ObjectDisposedException if I call _myTimer.Start() after leaving the using block.

How can _myTimer be around for the entire lifetime of my program?

question from:https://stackoverflow.com/questions/65617366/why-do-i-never-get-the-objectdisposedexception

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Calling Dispose doesn't remove the object or references to it. It will not be GCed as long as there are references to it. Dispose releases unmanaged resources within the object, which is likely but by no means guaranteed to cause at least some of its methods to stop working and start throwing ObjectDisposedException.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...