2011-05-25 54 views
1

我有一个VB.NET用户控件保存PDF文档,然后显示在WebBrowser控件中。代码如下所示:保存一个PDF文档似乎保留在内存中的引用(VB.NET)

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在程序完成时不会关闭)。我发现this这篇文章似乎暗示Adobe没有正确清理它,但实施其建议的更改似乎没有帮助。

为什么我会得到这种行为?在VB6中,没有正确关闭的程序总是由不清除的零散对象引用造成的。这在VB.NET中仍然如此吗?如果是这样,我能做些什么来确定哪个对象,或者为什么会发生这种情况?

+0

在.NET中,流浪对象引用不应该阻止程序关闭(至少如果它们是托管对象)。但是,任何仍在运行的线程都会阻止程序退出。也许还有一个线程在COM库中运行(可能是由于VB6对象引用的错误?)。另外,由于您使用COM,因此您应确保在Main方法中具有STAThread属性。 – Justin 2011-05-25 15:32:23

+0

对不起,当我说程序我不完全准确。这是一个用户控件(为了简单起见,我说的是程序)。可以/我应该还是使用STAThread? 有什么方法可以查看仍然有效的线程吗? – 2011-05-25 15:41:19

回答

1

我会分开了这一点:读取数据,写入数据,和查看数据:

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 

的Marshal.ReleaseComObject的调用在最后确保引用计数总是递减。冲洗和关闭不是必需的,因为Dispose也会这样做。 WebBrowser控件实现了IDisposable,所以我也使用了一个Using块。

0

你正在做的事情比我过去做得更复杂。但我可以告诉你,.NET中的PDF字节对象可以咀嚼非常大量的内存(即使处置)。我建议在文件服务器上使用临时文件(在运行Web服务器的机器上的实际目录中)。而不是将物体保存在记忆中。我知道程序集PDFSharp有一些很好的(和免费的)代码可以使用。但我不知道什么会阻止你的程序退出。祝你好运哥们。

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