9

In C#, using statement is used to dispose in a deterministic manner the resources without waiting for garbage collector. For example, it may be used to:

  • Dispose SQL commands or connections,

  • Close streams, freeing the underlying source like a file,

  • Free GDI+ elements,

  • etc.

I noticed that using is used more and more in cases where there is nothing to dispose, but where it's just more convenient for the caller to write a using block rather than two separate commands.

Examples:

  • MiniProfiler, written by Stack Overflow team, uses using to denote blocks to profile:

    using (profiler.Step("Name goes here"))
    {
        this.DoSomethingUseful(i - 1);
    }
    

    One alternative approach would be to have two blocks:

    var p = profiler.Start("Name goes here");
    this.DoSomethingUseful(i - 1);
    profiler.Stop(p);
    

    Another approach would be to use actions:

    profiler.Step("Name goes here", () => this.DoSomethingUseful(i - 1));
    
  • ASP.NET MVC also picked using for forms:

    <% using (Html.BeginForm())
       { %>
           <label for="firstName">Name:</label>
           <%= Html.TextBox("name")%>
           <input type="submit" value="Save" />    
    <% } %>
    

Is such usage appropriate? How to justify it, given that there are several drawbacks:

  • Beginners would be lost, since such usage doesn't correspond to the one which is explained in books and language specification,

  • The code should be expressive. Here, the expressiveness suffers, since the appropriate usage of using is to show that behind, there is a resource, like a stream, a network connection or a database which should be released without waiting the garbage collector.

10

3 Answers 3

8

Your last statement - that "the appropriate usage of using is to show that behind, there is a resource, like a stream, a network connection or a database which should be released without waiting the garbage collector" is incorrect, and the reason why is given at the documentation for the IDisposable interface: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

The primary use of this interface is to release unmanaged resources.

So, if your class uses any unmanaged resouces, it doesn't matter when you may or may not want GC to happen - it's got nothing whatsoever to do with GC as unmanaged resources aren't GC'ed (https://stackoverflow.com/questions/3607213/what-is-meant-by-managed-vs-unmanaged-resources-in-net).

So the purpose of "using" is not to avoid waiting on GC, it's to force a release of those unmanaged resources now, before the class instance goes out of scope and it's Finalize is called. This is important for reasons that should be obvious - an unmanaged resource may have dependencies on other unmanaged resources, and if they are disposed of (or finalized) in the wrong order Bad Things may happen.

So if the class being instanced in the using block uses any unmanaged resources, then then answer is yes - it is appropriate.

Note that IDisposable is not prescriptive about it being only for releasing unmanaged resources, however - just that this is it's primary purpose. It may be the case that the author of the class has some action that they want to enforce happening at a certain time, and implementing IDisposable may be a way of getting that to happen, but whether or not that's an elegant solution is something that can only be answered on a case-by-case basis.

Whichever, the use of "using" implies that the class implements IDisposable, so it doesn't violate code expressiveness; it makes it quite clear what's going on, in fact.

4
  • "The primary use of this interface is to release unmanaged resources." I say Microsoft's documentation sucks on that point. Maybe that's how they use it in the FCL, but application developers have been using it for a variety of things for close to a decade now - some for good reasons, some for not-so-good reasons. But quoting that chunk of their doc does not answer the OP's question at all. Commented Jan 24, 2013 at 21:42
  • 1
    Note my second last para - the primary purpose need not be the only purpose. IDisposable can be implemented for any reason whatsoever, and it provides a known interface with expected behaviour and usage style, so when you see it you know that there's something else that needs to happen before the instance can just be let go out of scope. The point is: if it implements IDisposable, then using is appropriate; everything else is just preamble. Commented Jan 24, 2013 at 21:52
  • 1
    You're basically saying the purpose is not avoid waiting for GC, it's avoid waiting for the finalizer. But I don't see the difference: finalizer is called by the GC.
    – svick
    Commented Jan 24, 2013 at 22:41
  • The GC operates in a non-deterministic manner - you don't know when it will be called. The GC also just calls the finalizer, but it doesn't do any disposing itself - the actual resource itself is outside of the GC's control. With using (1) the object is properly scoped, and (2) the disposal is known to happen at a known point in time - when it exits the scope of the using block, the unmanaged resource is gone (or - worst case - handed over to something else that will destroy it). Really, this is just nitpicking; read the documentation, it's all there are shouldn't need to be repeated. Commented Jan 24, 2013 at 23:35
8

The use of using implies the presence of a Dispose() method. Other programmers will assume that such a method exists on the object. Consequently, if an object is not disposable, you should not use using on it.

Code clarity is king. Either omit the using, or implement IDisposable on the object.

MiniProfiler appears to be using using as a mechanism to "fence in" the code being profiled. There is some merit to this; presumably, MiniProfiler is either calling Dispose() to stop a timer, or the timer is stopped when the MiniProfiler object goes out of scope.

More generally, you would invokeusing when some sort of finalization needs to occur automatically. The documentation for html.BeginForm states that, when the method is used in a using statement, it renders the closing </form> tag at the end of the using block.

That doesn't necessarily mean it's still not abuse.

9
  • 4
    So far so obvious. The question is, when (if at all) is it appropriate to implement IDisposable/Dispose() despite not having anything to dispose in the sense OP is describing?
    – user7043
    Commented Jan 24, 2013 at 20:43
  • 2
    I thought I made that clear; there isn't a time when that is appropriate. Commented Jan 24, 2013 at 20:44
  • 1
    My point is, Dispose is required for using to make sense at all (regardless of whether it's appropriate). OP's examples all implement Dispose, don't they? And IIUC, the question is whether it is correct that these classes use Dispose, rather than some other method (like Stop() for MiniProfiler).
    – user7043
    Commented Jan 24, 2013 at 21:00
  • 1
    Yeah, but that's not the question. The question is whether it's a good idea to do so.
    – user7043
    Commented Jan 24, 2013 at 21:05
  • 2
    @delnan: Again, I thought I made that clear. If it makes the intent of your code clearer, then it's a good idea. If it doesn't, it isn't. Commented Jan 24, 2013 at 21:06
1

using is error and exception safe. It ensures Dispose() will be called irregardless of any mistakes the programmer makes. It does not interfere with the catching or handling of exceptions, but the Dispose() method is executed recursively up the stack when an exception is thrown.

Objects that implement IDispose but have nothing to dispose when they are done. Are at best, future proofing their design. So that you don't have to refactor your source code, when in the future, they then need to dispose of something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.