locked
Do I need to Dispose a PrintDocument? RRS feed

  • Question

  • Hello,

    I am curious if a PrintDocument object needs to be disposed? I see that it has no Dispose method of its own, but does that mean it should not be called? I don't want to hold onto printer resources if they are no longer needed.

    Thanks!
    Thursday, October 15, 2009 3:35 PM

Answers

  • PrintDocument inherits from Component, which is IDisposable.  It does have a Dispose method .

    You should Dispose of your PrintDocument.  Typically, you'd do this by wrapping it in a using statement.

    using(PrintDocument pd = new PrintDocument())
    {
        pd.PrintPage += (this.pd_PrintPage);
        pd.Print();
    }
    
    


    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by MattPeterson Thursday, October 15, 2009 5:03 PM
    Thursday, October 15, 2009 3:54 PM

All replies

  • PrintDocument inherits from Component, which is IDisposable.  It does have a Dispose method .

    You should Dispose of your PrintDocument.  Typically, you'd do this by wrapping it in a using statement.

    using(PrintDocument pd = new PrintDocument())
    {
        pd.PrintPage += (this.pd_PrintPage);
        pd.Print();
    }
    
    


    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by MattPeterson Thursday, October 15, 2009 5:03 PM
    Thursday, October 15, 2009 3:54 PM
  • You should dispose any type that implements IDisposable.

    In the particular case of PrintDocument it does implement it (inherit frmo Component) so you should call Dispose on it
    Thursday, October 15, 2009 4:06 PM
  • No, you don't have to Dispose() it.  PrintDocument doesn't override Dispose() itself, it inherits the one from Component.  Component.Dispose() doesn't do anything unless the component was added to a container.  In other words, if you dropped PrintDocument from the toolbox onto a form. 

    Even that doesn't do anything important.  You can see the container created in any Windows Forms' Designer.cs file, it is the "components" variable.  It is only there to ensure that the Dispose() method is called on any component used by the form.  A Dispose() method that doesn't do anything in the case of PrintDocument.

    This is not an uncommon mishap with IDisposable.  Another good example is MemoryStream, it inherits Dispose() from Stream.  Disposing streams is almost always super important, there tends to be a kernel resource associated with it, like a file or a TCP/IP channel.  Not for MemoryStream, it is just memory.  Using the using statement with it is just wasted CPU cycles.

    Of course, these are implementation details that you can't guess accurately unless you know what Dispose() actually does.  In case of doubt, *always* choose the safe option.  Omitting it will make you look like a seasoned professional or a newbie, depending on how it looks and who looks at it.  The former will leave a comment in the code why it was omitted and how likely it is that a future .NET update will break the assumption.

    Hans Passant.
    Thursday, October 15, 2009 5:42 PM
  • No, you don't have to Dispose() it.  PrintDocument doesn't override Dispose() itself, it inherits the one from Component.  Component.Dispose() doesn't do anything unless the component was added to a container.  In other words, if you dropped PrintDocument from the toolbox onto a form. 

    Even that doesn't do anything important.  You can see the container created in any Windows Forms' Designer.cs file, it is the "components" variable.  It is only there to ensure that the Dispose() method is called on any component used by the form.  A Dispose() method that doesn't do anything in the case of PrintDocument.

    This is not an uncommon mishap with IDisposable.  Another good example is MemoryStream, it inherits Dispose() from Stream.  Disposing streams is almost always super important, there tends to be a kernel resource associated with it, like a file or a TCP/IP channel.  Not for MemoryStream, it is just memory.  Using the using statement with it is just wasted CPU cycles.

    Of course, these are implementation details that you can't guess accurately unless you know what Dispose() actually does.  In case of doubt, *always* choose the safe option.  Omitting it will make you look like a seasoned professional or a newbie, depending on how it looks and who looks at it.  The former will leave a comment in the code why it was omitted and how likely it is that a future .NET update will break the assumption.

    Hans Passant.
    This was my hang-up... I had actually taken a look via Reflector and found nothing that seemed to indicate a need for disposal. Thanks for clarifying this.

    Thursday, October 15, 2009 6:13 PM

  • Of course, these are implementation details that you can't guess accurately unless you know what Dispose() actually does.  In case of doubt, *always* choose the safe option.  Omitting it will make you look like a seasoned professional or a newbie, depending on how it looks and who looks at it.  The former will leave a comment in the code why it was omitted and how likely it is that a future .NET update will break the assumption.

    Hans Passant.

    And then when the next version of the framework is released you will have to go over all your code searching for comments and determining if the old assumption is still valid.
    Not very safe if you ask me ;)

    I would always go by the book in these cases, if a class implement IDisposable is because there is at least a possibility (as you mentioned a Component in a container) that you should dispose it, so go ahead and always dispose it.
    Thursday, October 15, 2009 7:14 PM
  • This was my hang-up... I had actually taken a look via Reflector and found nothing that seemed to indicate a need for disposal. Thanks for clarifying this.


    Yes, but did you check the parent class?
    If the parent has some disposing need then all the children should inherit that responsability.
    Thursday, October 15, 2009 7:15 PM
  • This was my hang-up... I had actually taken a look via Reflector and found nothing that seemed to indicate a need for disposal. Thanks for clarifying this.


    Yes, but did you check the parent class?
    If the parent has some disposing need then all the children should inherit that responsability.
    Not only that, but PrintDocument isn't a sealed class.  You should (theoretically) plan your code around the possibility that somebody may subclass it and use a subclass in the future, and the subclass is free to use Dispose() to do something meaningful.  Otherwise, you're violating the Liskov Substitution Principal .

    I agree completely with Ignacio here - if your class implements IDisposable, Dispose() it.  Even when it's technically (currently) not meaningful to do so.

    Reed Copsey, Jr. - http://reedcopsey.com
    Thursday, October 15, 2009 7:32 PM