2

This is mostly for curiosity's sake, as there are better ways of implementing almost any use case I can think of for this construct (in C# and other languages I use regularly, at least), but I recently saw on here a scoped mutex which was a cool concept.

My question is, does the using statement maintain a reference (ie: prevent the GC from running on) to the object it's acting on?

For example, if I were to do:

using (new ScopedMutex())
{
// ...
}

would the ScopedMutex object maintain its existence to the end of the using block, or could the GC run and dispose of it mid-block?

Community
  • 1
  • 1
Tanzelax
  • 5,406
  • 2
  • 25
  • 28

3 Answers3

6

No, the GC will not dispose it. A reference to that object is stored in a local variable (see this answer for more info). A local variable is considered a GC root and the object will be reachable from it (it needs to be reachable for the using block to be able to call Dispose on it).

Community
  • 1
  • 1
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • Oh, I feel silly now, of course it needs a reference for dispose to be called at the end... thanks. :) – Tanzelax Feb 24 '10 at 23:34
  • If the object in question is a sealed class, and has a do-nothing `Dispose` method, is there any specification that would forbid the JIT from inlining the "Dispose" to nothingness [as e.g. it would be forbidden from inlining `GC.KeepAlive`]? – supercat Feb 04 '14 at 20:06
  • @supercat I doubt it. To GC, `Dispose` is yet another method. `Finalize` (surfaced as destructor in C#) on the other hand is what GC cares about specifically and it does have optimizations for objects lacking explicit destructors. – Mehrdad Afshari Feb 04 '14 at 23:32
2

The C# compiler will implicitly create a variable for you. The using statement would actually be transformed into something like the following when compiled (you can use Redgate Reflector to see the exact code for yourself, btw):

ScopedMutex scopedMutex1 = new ScopedMutex();
try
{
    // ...
}
finally
{
    scopedMutex1.Dispose();
}
jrista
  • 32,447
  • 15
  • 90
  • 130
0

It will not dispose it in mid-block.

Orentet
  • 2,353
  • 1
  • 17
  • 28