0

I am creating an excel and powerpoint document using openxml. As I do not want to create emtpy file, I want to be sure to write the document only when it is complete using my own Save methods. It works weel.

Though, during development, when it crashes, it usually block the DLL file for a while. I was thinking that IDisposable was not properly called. Is there a way to define a using in my class properties _MemStream?

public partial class Presentation
{
  public Pa.PresentationDocument PresentationDoc { get; set; }   //PresentationPart parts
  private MemoryStream _MemStream { get; set; }

  public void Init(string FileName = "NoName")
  {
    //Init stream
    this._MemStream = new MemoryStream();
    this.PresentationDoc = Pa.PresentationDocument.Create(
    this._MemStream, PresentationDocumentType.Presentation);
    // Create the presentation
  }
  public string Save(string path)
  {
    this.PresentationDoc.Close();
    using (FileStream fileStream = new FileStream(FileTemp,
    System.IO.FileMode.CreateNew))
    {
      this._MemStream.WriteTo(fileStream);
    }

    this._MemStream.Flush();
  }
}
Simon Bull
  • 851
  • 6
  • 14
Yoyo
  • 101
  • 1
  • 11
  • 1
    `IDisposable` [isn't going to help if your process terminates](http://stackoverflow.com/a/34464312/993547). – Patrick Hofman Jun 23 '16 at 09:49
  • This is what I am looking for: Is there a way to use "using" for a class properties, instead of within the method? Like private MemoryStream _MemStream { get; using( set); } – Yoyo Jun 23 '16 at 12:10

2 Answers2

0

The Dispose method in not called by magic. If your class creates disposable members, then the class itself it should implement the IDisposable interface and call the Dispose method of those members. If the class creates disposable instances in a method scope, the those instances should call the Dispose method.

So the Presentation should implement the IDisposable interface where you dispose the _MemStream and possible.

A client which uses the Presentation class should call the Dispose method, the framework doesn't do this for us.

Adrian Iftode
  • 15,465
  • 4
  • 48
  • 73
  • Being relatively new to c#, my question was more: I am pretty sure I have to do it, but what is the best way? Thank you – Yoyo Jun 23 '16 at 10:00
  • https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/ You don't need to add the finalizer too. – Adrian Iftode Jun 23 '16 at 10:12
0

As Adrian says, things are not disposed by magic. So one way to start disposing is to make Presentation implement IDisposable itself and then dispose of your resources there.

For example:

public partial class Presentation : IDisposable
{
  public Pa.PresentationDocument PresentationDoc { get; set; }   //PresentationPart parts
  private MemoryStream _MemStream { get; set; }

  public void Init(string FileName = "NoName")
  {
    //Init stream
    this._MemStream = new MemoryStream();
    this.PresentationDoc = Pa.PresentationDocument.Create(
      this._MemStream, PresentationDocumentType.Presentation);
    // Create the presentation
  }
  public string Save(string path)
  {
    this.PresentationDoc.Close();
    using (FileStream fileStream = new FileStream(FileTemp,
      System.IO.FileMode.CreateNew))
    {
      this._MemStream.WriteTo(fileStream);
    }

    this._MemStream.Flush();
  }

  public void Dispose()
  {
    if(_MemStream != null)
    {
      _MemStream.Dispose();
    }
  }
}
Simon Bull
  • 851
  • 6
  • 14
  • I think PresentationDoc.Close should be moved in the Dispose method since it's likely to be a dispose method. – Adrian Iftode Jun 23 '16 at 10:14
  • I recall I cannot write the document to a stream if it is not closed. This is why it is in Save. Basically the save methods is the end. Once saved, does this.Dispose would be usefull? – Yoyo Jun 23 '16 at 12:12
  • You should not call dispose inside the instance itself. It will cause exceptions if the caller does not realise and wraps it in a using of their own. Just use the using clause in the caller to dispose. You can always track the validity of save internally to the class and throw an exception if a subsequent save is attempted – Simon Bull Jun 23 '16 at 16:12
  • Thx for all ansers! I am doing this. Should dispoable should be used for every heavy class? (I am creating up to 200 pptx ~3mo in this case) – Yoyo Jun 24 '16 at 08:32
  • Your classes should implement IDisposable whenever, at an instance level, they use any unmanaged resources or any managed resources that implement IDisposable. – Simon Bull Jun 24 '16 at 10:43