Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 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 Reply

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...