2011-05-25 6 views
1

PDF文書を保存してWebブラウザコントロールに表示するVB.NETユーザーコントロールがあります。コードは次のようになります。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関連データを取得し、VB6で書かれた、COM相互運用ライブラリです。

私の知る限り、このコードはPDF文書への参照を保持しています(プログラムが終了するとVB.NETが終了しないため)。私はthisを見つけましたが、それはadobeがそれ自体を適切にクリーンアップしないことを暗示しているようですが、その推奨変更を実装することは役に立たないようです。

どうしてこの現象が発生するのでしょうか? VB6では、正しく終了しないプログラムは、常にクリアされていない浮遊オブジェクト参照の結果でした。これはVB.NETでもまだ当てはまりますか?もしそうなら、私はどのオブジェクトを特定するために、あるいはこれが起こっているのかを特定するために何をすることができますか?

+0

.NETでは、迷子オブジェクト参照は、少なくとも管理対象オブジェクトの場合、プログラムの終了を妨げません。ただし、実行中のスレッドがあれば、プログラムが終了することはありません。おそらくCOMライブラリにスレッドが残っているのでしょうか(おそらく、VB6のオブジェクト参照の迷惑行為によるものでしょうか?)また、COMを使用しているので、MainメソッドにSTAThread属性があることを確認する必要があります。 – Justin

+0

申し訳ありませんが、私がプログラムを言ったとき、私は完全に正確ではありませんでした。これはユーザーコントロールです(私は簡単のためにプログラムを言っています)。私はまだSTAThreadを使うことができますか? まだアクティブなスレッドを表示する方法はありますか? –

答えて

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がこれを行うため、FlushとCloseは必要ありません。 WebBrowserコントロールはIDisposableを実装しているので、Using Blockも使用しています。

0

あなたは私が過去に行ったことよりも何かもっと複雑なことをしています。しかし、.NETのPDFバイトオブジェクトは(たとえ処分されていても)非常に大量のメモリを噛み砕く可能性があることをお伝えします。私はあなたのファイルサーバー上の一時ファイルを使用することをお勧めします(あなたのWebサーバーを実行しているマシンの実際のディレクトリにあります)。オブジェクトをメモリに保持するのではなく。私はアセンブリを知っていますPDFSharpはあなたが使用できるいくつかの良い(そして無料の)コードを持っています。しかし、あなたのプログラムが何を出るのを妨げるのか分かりません。あなたにおじいちゃんに幸運。

PS:自分でガベージコレクタを呼び出すことをおすすめします。そして、あなたはVisual Studioであなたのスレッドを見ることができるはずです。 w3wp.exe(Windows 7のIIS 7プロセス)プロセスに接続すると、コンテキストメニュー([デバッグ] - > [Windows] - > [スレッド])が表示されます。 COMスレッドがそこに表示されるかどうかはわかりませんが。