我正在开发一个可以打开和显示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文档,会弹出一个异常,说明要删除的文件仍在使用中。
我的代码中有什么地方出错或遗漏了吗?
谢谢!
发布于 2008-11-14 07:46:06
使xpsDocument成为成员,然后不要对其调用close() :)
发布于 2009-09-02 21:24:53
您需要关闭从中打开分配给查看器的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这样做是“为了”你在幕后,忘记了自己清理。
发布于 2008-11-12 05:07:15
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)获取托管堆栈跟踪和查看。
https://stackoverflow.com/questions/283027
复制相似问题