Jan Petter Jetmundsen
Jan Petter Jetmundsen

Reputation: 585

Calling dispose within list.removeAll

I'm pretty new to C# programming, and the concept of the GC, and its realtions to IDisposable is still a bit vague. What does calling Dispose mean in terms of the garbage collection? Specifically i wonder if the following code may fail occationally, depending on when the garbage collection kicks in. (I have not been able to make it crash during my tests).

//List<TestClass2> tc2List;
//TestClass2 invokes a thread. It implements IDisposable. 
//Its Dispose() sets a stop-condition for the thread,
//and joins the thread, awaiting it to stop. (may take 100 msek)

tc2List.RemoveAll(t =>
{
  if (String.Compare(t.Name, "Orange") == 0)
  {
    t.Dispose(); //May take up to 100 msek
    return true;
  }
  return false;
});

Upvotes: 3

Views: 852

Answers (4)

Henk Holterman
Henk Holterman

Reputation: 273179

i wonder if the following code may fail occationally, depending on when the garbage collection kicks in

No, it won't fail

//Its Dispose() sets a stop-condition for the thread,
//and joins the thread, awaiting it to stop. (may take 100 msek)

That is a slightly a-typical use of Dispose() but not wrong. A more efficient approach would use a different Stop() so that you can stop all threads at once. Or call Dispose() from Parallel.ForEach(). But whatever method you choose, it is not hindering, nor is it being hindered by, the GC.

Upvotes: 2

Soundararajan
Soundararajan

Reputation: 2194

What does calling Dispose mean in terms of the garbage collection?

Calling dispose, means you are forcibly cleaning up things (literally the memory) using your implementation of the Dispose method. Note : (Some of the framework classes do call your implementation of Dispose for you. System.Windows.Forms.Form for example)

Garbage collection on the contrast is a feature of the .NET runtime that will clean up things for you automatically. Automatically i mean, because its up to the memory pressure and other factors that is taken care by the runtime.

A simple strategy i would recommend. Do Dispose() if you think that the memory would stay longer than needed and would impact the application. Else leave it to the runtime, it will automatically cleans up (i.e finalizes) the objects when they go out of scope. The GC has its own algorithm on how to do cleanup, but you can to a greater extent rely on it.

The next question Specifically i wonder if the following code may fail occasionally, depending on when the garbage collection kicks in

I guess no. Failure of the code due to GC kicking in, depends on how you write the finalizer of TestClass2. Definitely your call t.Dispose() wont clash with the GC.

Upvotes: 0

CodesInChaos
CodesInChaos

Reputation: 108790

Your code works, but it's bad style. Predicates should not have side effects. So you should first dispose the elements, and then remove them.

Predicate<T> filter = t => t.Name == "Orange";
foreach(var t in tc2List.Where(filter))
  t.Dispose();
tc2List.RemoveAll(filter);

Upvotes: 4

D J
D J

Reputation: 7028

Do you have finalize method in you TestClass2?

Dispose main properties

  1. This has to be implemented in classes implementing IDispose interface.
  2. Its the right place for freeing-up unmanaged resources like file, handles, and connections etc.
  3. Dispose() method is called explicitely in the code itself.
  4. Dispose() method is automatically called (for objects which implement IDispose), when used in a "using"

Refer to link.

Upvotes: 1

Related Questions