保存 PDF 文档似乎是在内存中保留引用(VB.NET)

发布于 2024-11-09 16:10:41 字数 721 浏览 0 评论 0原文

我有一个 VB.NET 用户控件,它保存 PDF 文档,然后在 WebBrowser 控件中显示该文档。代码如下:

Using myPdfDoc As New FileStream(fileName, FileMode.Create)
    Dim byt As Byte() = comLib.GetData();
    If Not byt Is Nothing Then                        
        myPdfDoc.Write(byt, 0, byt.Length)
        myPdfDoc.Flush()
        myPdfDoc.Close()

        webBrowserCtl.Navigate(fileName)
    End If
End Using

comLib 是一个 COM 互操作库,用 VB6 编写,用于获取相关数据。

据我所知,这段代码保留了对 PDF 文档的引用(因为程序完成时 VB.NET 不会关闭)。我发现 这篇 文章似乎暗示 adobe 没有正确清理自身,但实施它建议的更改似乎没有帮助。

为什么我会出现这种行为?在 VB6 中,程序无法正确关闭总是由于未清除杂散对象引用而导致的。这在 VB.NET 中仍然如此吗?如果是这样,我该如何识别哪个对象,或者为什么会发生这种情况?

I have a VB.NET user control that is saving a PDF document and then displaying that in a WebBrowser control. The code looks like this:

Using myPdfDoc As New FileStream(fileName, FileMode.Create)
    Dim byt As Byte() = comLib.GetData();
    If Not byt Is Nothing Then                        
        myPdfDoc.Write(byt, 0, byt.Length)
        myPdfDoc.Flush()
        myPdfDoc.Close()

        webBrowserCtl.Navigate(fileName)
    End If
End Using

comLib is a COM interop library, written in VB6 that obtains the relevant data.

As far as I can tell, this code is keeping a reference to the PDF document (as VB.NET does not close when the program finishes). I found this article which seems to imply that adobe doesn't clean up after itself properly, but implementing its suggested changes doesn't seem to help.

Why might I be getting this behaviour? In VB6, a program not closing properly was always a result of stray object references that are not cleared up. Is this still true in VB.NET? If so, what can I do to identify which object, or why this might be happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独患者 2024-11-16 16:10:41

我将把它分开:读取数据、写入数据和查看数据:

Dim byt As Byte() = Nothing
Try
  byt = comLib.GetData()
Finally
  If Not comLib Is Nothing Then
    Marshal.ReleaseComObject(comLib)
  End If
End Try

If Not byt Is Nothing Then
  Using myPdfDoc As New FileStream(fileName, FileMode.Create)
    myPdfDoc.Write(byt, 0, byt.Length)
  End Using

  Using webBrowserCtl As New WebBrowser()
    webBrowserCtl.Navigate(fileName)      
  End Using
End If  

Finally 中的 Marshal.ReleaseComObject 调用确保引用计数始终递减。 Flush 和 Close 不是必需的,因为 Dispose 无论如何都会执行此操作。 WebBrowser 控件实现 IDisposable,因此我也为此使用了一个Using 块。

I would separate this out: reading the data, writing the data, and viewing the data:

Dim byt As Byte() = Nothing
Try
  byt = comLib.GetData()
Finally
  If Not comLib Is Nothing Then
    Marshal.ReleaseComObject(comLib)
  End If
End Try

If Not byt Is Nothing Then
  Using myPdfDoc As New FileStream(fileName, FileMode.Create)
    myPdfDoc.Write(byt, 0, byt.Length)
  End Using

  Using webBrowserCtl As New WebBrowser()
    webBrowserCtl.Navigate(fileName)      
  End Using
End If  

The Marshal.ReleaseComObject call in the Finally ensures that the reference count is always decremented. The Flush and Close are not necessary, as Dispose will do this anyway. The WebBrowser control implements IDisposable, so I have used a Using block for that too.

≈。彩虹 2024-11-16 16:10:41

你正在做的事情比我过去所做的要复杂得多。但我可以告诉您,.NET 中的 PDF 字节对象会占用大量内存(即使已释放)。我建议在文件服务器上使用临时文件(在运行 Web 服务器的计算机上的实际目录中)。而不是将对象保留在内存中。我知道程序集 PDFSharp 有一些可以使用的优秀(且免费)代码。但我不知道什么会阻止你的程序退出。祝你好运,伙计。

PS:您可能想尝试自己调用垃圾收集器。您应该能够在 Visual Studio 中看到您的线程。当您附加到 w3wp.exe(Windows 7 中的 IIS 7 进程)进程时,您将获得一个上下文菜单(“调试”->“Windows”->“线程”)。虽然我不知道 COM 线程是否会显示在那里。

You are doing something way more complicated than what I have done in the past. But I can tell you that PDF byte objects in .NET can chew up extremely large amounts of memory (even if disposed). I'd suggest using temp files on your file server (in an actual directory on the machine running your web server). Rather than keeping the objects in memory. I know the assembly PDFSharp has some good (and free) code you can use. But I do not know what would prevent your program from exiting. Good luck to you buddy.

PS: You may want to try calling the garbage collector on your own. And you should be able to see your threads in Visual Studio. When you attach to your w3wp.exe (IIS 7 process in Windows 7) process, you will get a context menu (Debug->Windows->Threads). Although I don't know if a COM thread would show in there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文