10

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 ドキュメントでは、削除するファイルがまだ使用されているという例外が表示されます。

私のコードに何か問題や不足がありますか?

ありがとう!

4

6 に答える 6

7

ビューアーに割り当てられた 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 を Package で開いておらず、それが何であるかさえ知らないかもしれませんが、.NET は舞台裏で「あなたのために」それを行い、その後のクリーンアップを忘れています。

于 2009-09-02T21:24:52.670 に答える
2

xpsDocument をメンバーにしてから、close() を呼び出さないでください :)

于 2008-11-14T07:46:06.217 に答える
0

http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic59281.aspxと同じ問題が発生していると思われ ます

DocumentViewer のバグのように聞こえます。クローズ時にネストされた BitmapDecoders を破棄するか、別のビットマップ キャッシュ オプションを使用してイメージをロードする必要があります。

于 2008-12-19T09:54:03.373 に答える
0

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 )を介して調べることもできます。

于 2008-11-12T05:07:14.563 に答える
0

いいえ、今のところまだ何もありません。

列挙するために、失敗した次の方法を試しました。

  1. ファイルを削除する前に、ウィンドウの「Closed」イベントですべてを null に設定します。これには、DocumentViewer.Document プロパティと DocumentViewer オブジェクトが含まれます。

  2. ShowDialog() を使用してウィンドウを開き、後で null に設定しました。ファイルの削除を、ウィンドウを開いている System.Windows.Application オブジェクトの「Exit」イベントに移動しました。ファイルが使用されているという例外がまだスローされます。

ドキュメントビューアのバグ???

于 2008-11-14T03:11:18.660 に答える
0

返信いただきありがとうございます!

少し低レベルですが、アイデアが尽きたら覚えておきます。とにかく、私はバグについてもう少し知りました。例外の原因となった特定のドキュメントには、画像が挿入されています。画像を削除すると、例外は発生しません。これはおそらくDocumentViewerのバグかもしれませんが、私はまだ試しています...

于 2008-11-13T08:19:11.740 に答える