WPF DocumentViewer不会释放XPS文件

10 .net wpf documentviewer xps

我正在开发一个打开并显示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();
Run Code Online (Sandbox Code Playgroud)

用于导航XPS文档:

m_documentViewer.FirstPage();
m_documentViewer.LastPage();
m_documentViewer.PreviousPage();
m_documentViewer.NextPage();
Run Code Online (Sandbox Code Playgroud)

要关闭DocumentViewer对象并删除文件:

m_documentViewer.Document = null;
m_documentViewer = null;
File.Delete(xpsfilename);
Run Code Online (Sandbox Code Playgroud)

这一切都非常基础,它适用于我们测试的其他文档.但是对于特定的XPS文档,会弹出一个异常,说明要删除的文件仍在使用中.

我的代码有什么问题或遗漏吗?

谢谢!

Tim*_*son 6

您需要关闭System.IO.Packaging.Package,从中打开分配给查看器的XpsDocument.此外,如果您希望能够在同一应用程序会话中再次打开同一文件,则必须从PackageStore中删除Package.

尝试

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);
Run Code Online (Sandbox Code Playgroud)

是的,我知道你可能没有用一个包打开XpsDocument,甚至可能都不知道是什么 - 或者关心 - 但.NET在幕后"为你"做了这件事并且忘了自己清理.


moo*_*ogs 2

使 xpsDocument 成为成员,然后不要对其调用 close() :)