WPF DocumentViewerはXPSファイルをリリースしません
-
08-07-2019 - |
質問
XPSドキュメントを開いて表示するWPFアプリケーションで作業しています。アプリケーションが終了すると、アプリケーションは、クリーンアップのために開いたXPSドキュメントを削除する必要があります。ただし、特定のXPSドキュメントを開くと、アプリケーションは、ファイルを削除しようとしたときにファイルがまだ使用中であるという例外をスローします。特定のXPSドキュメントを開き、最初のページを超えて移動した場合にのみ発生するため、少し奇妙です。
使用したコードの一部を以下に示します:
XPSドキュメントを開く場合:
DocumentViewer m_documentViewer = new DocumentViewer();
XpsDocument m_xpsDocument = new XpsDocument(xpsfilename, fileaccess);
m_documentViewer.Document = m_xpsDocument.GetFixedDocumentSequence();
m_xpsDocument.Close();
XPSドキュメントをナビゲートする場合:
m_documentViewer.FirstPage();
m_documentViewer.LastPage();
m_documentViewer.PreviousPage();
m_documentViewer.NextPage();
DocumentViewerオブジェクトを閉じてファイルを削除するには:
m_documentViewer.Document = null;
m_documentViewer = null;
File.Delete(xpsfilename);
これはすべて非常に基本的なもので、テストした他のドキュメントでも機能します。しかし、特定のXPSドキュメントでは、削除するファイルがまだ使用されているという例外がポップアップ表示されます。
コードに何か間違いや欠落がありますか?
ありがとう!
解決
xpsDocumentをメンバーにし、その上でclose()を呼び出さないでください:)
他のヒント
ビューアに割り当てられたXpsDocumentを開いたSystem.IO.Packaging.Packageを閉じる必要があります。さらに、同じアプリケーションセッション内で同じファイルを再度開くことができるようにするには、PackageStoreからパッケージを削除する必要があります。
試用
var myXpsFile = @"c:\path\to\My XPS File.xps";
var myXpsDocument = new XpsDocument(myXpsFile);
MyDocumentViewer.Document = myXpsDocument;
//open MyDocumentViwer's Window and then close it
//NOTE: at this point your DocumentViewer still has a lock on your XPS file
//even if you Close() it
//but we need to do something else instead
//Get the Uri from which the system opened the XpsPackage and so your XpsDocument
var myXpsUri = myXpsDocument.Uri; //should point to the same file as myXpsFile
//Get the XpsPackage itself
var theXpsPackage = System.IO.Packaging.PackageStore.GetPackage(myXpsUri);
//THIS IS THE KEY!!!! close it and make it let go of it's file locks
theXpsPackage.Close();
File.Delete(myXpsFile); //this should work now
//if you don't remove the package from the PackageStore, you won't be able to
//re-open the same file again later (due to System.IO.Packaging's Package store/caching
//rather than because of any file locks)
System.IO.Packaging.PackageStore.RemovePackage(myXpsUri);
はい、おそらくパッケージでXpsDocumentを開いていなかったので、パッケージが何であるかさえ気にかけないかもしれませんが、.NETはそれを「のために」しました。あなたは舞台裏で自分自身の後片付けを忘れています。
http ://blogs.msdn.com/junfeng/archive/2008/04/21/use-htrace-to-debug-handle-leak.aspx
WinDbgを使用して、誰がハンドルとアンマネージスタックを保持しているかを把握できます
編集:そしてもちろん、管理されたスタックトレースを取得し、SOS拡張機能( http://msdn.microsoft.com/en-us/library/bb190764.aspx )
返信ありがとうございます!
これは少し低レベルですが、アイデアがなくなったときに心に留めておきます。 とにかく、バグについてもう少し知りました。例外の原因となる特定のドキュメントには、画像が挿入されています。画像を削除しても、例外は発生しません。これはDocumentViewerのバグかもしれませんが、私はまだ試しています...
いや、今のところまだ何もありません。
列挙するために、次の失敗したメソッドを試しました:
-
" Closed"ですべてをnullに設定します。ファイルを削除する前のウィンドウのイベント。これには、DocumentViewer.DocumentプロパティとDocumentViewerオブジェクトが含まれます。
-
ShowDialog()を使用してウィンドウを開き、後でnullに設定したファイルの削除を「終了」に移動しました;ウィンドウを開いているSystem.Windows.Applicationオブジェクトのイベント。それでもファイルが使用されているという例外をスローします。
DocumentViewerのバグ???
と同じ問題が発生していると思われます http://www.devnewsgroups.net/group/microsoft。 public.dotnet.framework / topic59281.aspx
DocumentViewerのバグのように聞こえますが、ネストされたBitmapDecoderを破棄するか、別のビットマップキャッシュオプションで画像をロードする必要があります。