Mike
Mike

Reputation: 3284

Does setting an object to null dispose the object deterministically?

I have bit of an odd question and I could't find a clear answer to this even though there are threads bordering around the same question.

Question:If I set an object to null, will that cause the dispose method (implemented) be called deterministically? For example in the following code, by setting pricingEnvironment object to null, will Dispose get called immedietly? I understand that the finalizer will kick off for pricingEnvironment object at some point if Dispose is not called though.

Code:

public interface IPricingService
    {
        double GetPrice(string instrument);
    }

    public interface IPricingEnvironment:IDisposable
    {
        void Initialize();
    }

    public class PricingEnvironment : IPricingEnvironment
    {
        public void Dispose()
        {
            DisposeObject();
        }

        public void Initialize()
        {
            //initialize something leaky
        }

        private void DisposeObject()
        {
            //release some leaky unmanaged resource
        }

        ~PricingEnvironment()
        {
            DisposeObject();
        }
    }

    public class PricingService:IPricingService, IDisposable
    {
        private IPricingEnvironment pricingEnvironment;
        public PricingService()
        {
            pricingEnvironment = new PricingEnvironment();
        }
        public double GetPrice(string instrument)
        {
            pricingEnvironment.Initialize();
            return 1d;
        }

        public void Dispose()
        {
            //Will this dispose the leaky resource used by pricing environment deterministically?
            pricingEnvironment = null;
        }
    }

Thanks, -Mike

Upvotes: 4

Views: 475

Answers (5)

Luis Filipe
Luis Filipe

Reputation: 8708

I guess you're confusing disposing with being garbage collected.

Dispose frees non-managed resources (a Database connection or a file handle)

GC frees occupied memory by no longer used objects

Disposing is deterministic because it runs when you call Dispose (whether explicitly or implicitly in a using block)

Garbage collection is, by nature, non-deterministic. It runs when it fits to. Only then it may free a memory reference. For instance, If GC is running a generation level different from the one where the object is currently on, it will not be collected.

You may run GC explicitly by calling GC.Collect() but ask yourself if you should be second guessing the GC.

Upvotes: 0

rene
rene

Reputation: 42414

No, it will not.

do this:

    public void Dispose()
    {
        // check if object has IDisposble implemented
        IDisposable disposePricing = pricingEnvironment as IDisposable;
        if (disposePricing!=null)
        {
            disposePricing.Dispose();
        }
    }

and have a read on this CLR Inside Out article from 2007

Upvotes: 1

Dirk Vollmar
Dirk Vollmar

Reputation: 176159

There is no guarantee in .NET that the finalizer is ever called. The garbage collector may simply not call it (e.g. because there simply is no need for the garbage collector to ever free memory), and in the case one finalizer throws an exception, other finalizers will not execute (see MSDN). You can even suppress finalizers if you call SuppressFinalizer on the object.

Having said that, there is of course also no guarantee that the finalizer is called immediately (it might be called much later or not at all).

You either should explicitly call Dispose or make use of the using-statement so that your objects get properly disposed. As a safety net, you can still call Dispose from the finalizer. In fact, that's a best practice also demonstrated by the example in MSDN.

A good read on the topic is Raymond Chen's post:

Everybody thinks about garbage collection the wrong way

Upvotes: 3

dcastro
dcastro

Reputation: 68640

There is no* way to determine when the Garbage Collector will collect your object and call its finalizer (and, following the logic in your code, the Dispose method). Here's a good example of how unpredictable garbage collection is: http://ericlippert.com/2013/06/10/construction-destruction/

And even when the GC kicks in and collects the first generation of objects, your instance of PricingEnvironment will survive the first collection and be put on the finalization queue instead.

You should dispose of your objects deterministically, by either calling Dispose explicitly or using a using block.

*You can actually force it with GC.Collect(), but you shouldn't do that.

Upvotes: 0

DusteD
DusteD

Reputation: 1410

While computers are by definition deterministic, when allocated memory is released, is entirely up to the garbage collector of the implementation of the language. Setting it null will of cause decrease the reference count to the allocated memory, but that would happen in any case when the end of scope is reached.

Upvotes: 0

Related Questions