2011-05-25 50 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線程是否會顯示在那裏。