Search code examples
c#.net.net-coregembox-pdf

How to keep the MemoryStream from being closed automatically


I have a memory stream in a function like so

using var document = new PdfDocument();
var memoryStream = new MemoryStream();
document.Save(memoryStream, new GemBox.Pdf.PdfSaveOptions());
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;

It seems like as soons the function returns, the memoryStream is Disposed, later access will throws

System.ObjectDisposedException: Cannot access a closed Stream.
  • I would like to use this MemoryStream by seeking to 0 and read again and again later. How can I achieve that?

  • If I am using CopyTo, then the new MemoryStream is kept open but is that hugely inefficient? As I understand, the CopyTo will read the whole backing memory and write to the new Stream, basically double the memory usage? The result I received from CopyTo is what I wanted, I am just not sure if that is the right way or if there are better alternatives

      using var document = new PdfDocument();
      var memoryStream = new MemoryStream();
      document.Save(memoryStream, new GemBox.Pdf.PdfSaveOptions());
      memoryStream.Seek(0, SeekOrigin.Begin);
      var newStream = new MemoryStream();
      memoryStream.CopyTo(newStream);
      newStream.Seek(0, SeekOrigin.Begin);
      return newStream;
    

Sample Repro https://dotnetfiddle.net/mCZhug

Callstack at dispose time enter image description here


Solution

  • The reason why it's closed is because the stream ends up being disposed with the PdfDocument.Dispose() call, that is the whole point of that method.

    There are two ways how you can resolve your issue, first is to not call PdfDocument.Dispose() (in other words, remove the using statement):

    var document = new PdfDocument();
    var memoryStream = new MemoryStream();
    // ...
    

    The second solution is this:

    using var document = new PdfDocument();
    document.CloseStream = false;
    var memoryStream = new MemoryStream();
    // ...
    

    Setting the PdfDocument.CloseStream option to false has the same effect as not calling PdfDocument.Dispose().