MemoryStream,无法访问已关闭的流

13
使用sharpPDF库生成pdf内存流,然后想直接通过电子邮件发送。但是ms.Seek(....行会抛出ObjectDisposedException异常。

无法访问已关闭的流。

pdf.CreatePDF方法接受输出文件名的字符串或(out)Stream。但我猜它也关闭了流?我不习惯使用流,所以如果您能请指导应该如何完成这个任务?

可以在此处找到CreatePDF方法的sharpPDF源代码:

http://www.java2s.com/Open-Source/CSharp/PDF/SharpPDF/sharpPDF/pdfDocument.cs.htm

Public Sub SendPDF()
   Dim pdf As New sharpPDF.pdfDocument("Title", "Author")

   '....Generate pdf content

   Dim ms As New IO.MemoryStream
   pdf.CreatePDF(ms)

   Dim email As New EmailService
   email.Send(ms)

End Sub

Public Class EmailService
   Public Sub Send(Byval ms as Stream)
        ms.Seek(0, IO.SeekOrigin.Begin)

        Dim atc As New Attachment(ms, "Report.pdf")
        mail.Attachments.Add(atc)

        '....set other email parameters

        client.SendAsync(mail, mail.Subject)
  End Sub 
End Class

请展示创建 ms 的代码。 - sll
@sll是第三方库,我已经添加了链接。 - bretddog
很可能是pdf.CreatePDF(ms)关闭了ms。 - Joakim
1个回答

38

一个简单的方法是从关闭的MemoryStream中获取字节数组并创建另一个MemoryStream:

pdf.CreatePDF(ms)
ms = new MemoryStream(ms.ToArray())

Dim email As New EmailService
email.Send(ms)

请注意,在已关闭/释放的 MemoryStream 实例上调用MemoryStream.ToArray是可以的。这甚至在文档中有说明:

注意
当 MemoryStream 已关闭时,此方法也能工作。


2
Jon,如果OP收到了ObjectDisposedException,那么访问任何成员(假设实现了可处理模式)可能都是不可能的。 - Igby Largeman
2
@Charles:不对-您仍然可以在已释放的MemoryStream上调用ToArray。我会进行编辑以澄清这一点。 - Jon Skeet
1
哦,太酷了。(我应该知道Jon Skeet不会犯这样的愚蠢错误。) - Igby Largeman
文档仅提到了在“关闭”时的情况。 “Disposed”不是有点不同吗? 在处理后,GC是否可以收集它? - NoOne
@JonSkeet 嗯,由于限制工作集和更小的文件大小,我做得还可以,但总体性能非常慢...我正在一个Web服务器上压缩并输出一本充满PDF图像的书(500页)。我希望操作只需要15秒,而不是2分钟...(在这种情况下,3个缓冲区很容易将15秒提高到30秒,所有这些都会累加。实际上,现在PDFSharp不幸地将15秒提高到了一分钟以上。我可能不得不为PDF编写自己的元数据工具。)谢天谢地,对于后置页面,我只需进行字符串搜索\n%% - user645280
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接