Bassam Alugili
Bassam Alugili

Reputation: 16993

Did the compiler set the disposed objects to null?

I have the following code:

public class Program
{
 private static Task task;
 private static int counter = 0;

 private static void Main(string[] args)
 {
   for (int i = 0; i < 10; i++)
   {
    if (task == null)
    {
      Console.WriteLine(++counter);
    }

     using (task = new Task(Method))
     {
       task.Start();
       task.Wait();
     }

     //  task = null;

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

   Console.ReadKey();
 }

 public static void Method() { }
 }

My excepted output: 1 2 3 4 5 6... but the real output from this method is 1!

If I remove the comment from the code line Task = null; then I will became the expected result.

Why the disposed tasks are not null!? I thought, if the objects are disposed then they can be set to null from the GC (I have forced the GC to collect) in other words the GC will collect the disposed(orphan) objects and put them to null?!

Upvotes: 2

Views: 102

Answers (3)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

Am not sure about what you mean by compiler. If you mean "c# compiler" it has no business while the code is executing. It just compiles the c# code to IL. That's it, rest all taken care by CLR and JIT.

And for your question: No, nobody sets reference to null when disposed. It's you, your responsibility to set to null when you don't need it.

GC will collect only unreachable objects. In other words when you have no managed references to your instance it is eligible for garbage collection.

Upvotes: 2

Mike Strobel
Mike Strobel

Reputation: 25623

All static fields, like your task field, are GC roots. Objects reachable from GC roots will not be collected.

The GC also does not null-out references, and would not need to, as an unreachable object would not have any live references in scope of any threads.

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1062540

Why would you expect it to be set to null? using/Dispose() never says that it will do that. It promises to dispose it. The best practice here is to use a separate variable in the using statement to avoid confusion:

using(var t = new Task(Method))
{
    t.Start();
    t.Wait();
}

But if you want it set to null; set it to null:

task = null;

As for your other point:

in other words the GC will collect the disposed(orphan) objects and put them to null?!

The GC never sets anything to null either; it collects things that are unreachable: that is all

Upvotes: 6

Related Questions