Ответ 1
Сделайте xpsDocument членом, затем не вызывайте его():)
Я работаю над приложением WPF, которое открывает и отображает документы XPS. Когда приложение закрывается, спецификация - это приложение, которое должно удалить открытый документ 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 членом, затем не вызывайте его():)
Вам нужно закрыть пакет System.IO.Packaging.Package, из которого был открыт XpsDocument, назначенный для просмотра. Кроме того, если вы хотите снова открыть тот же файл в одном сеансе приложения, вам придется удалить пакет из PackageStore.
Try
var myXpsFile = @"c:\path\to\My XPS File.xps";
var myXpsDocument = new XpsDocument(myXpsFile);
MyDocumentViewer.Document = myXpsDocument;
//open MyDocumentViwer 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 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 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
EDIT: И, конечно же, вы можете также получить трассировку управляемого стека и вытолкнуть ее через расширение SOS (http://msdn.microsoft.com/en-us/library/bb190764.aspx)
Спасибо за ответ!
Это немного низкоуровневый, но я буду иметь в виду, когда у меня заканчиваются идеи. Во всяком случае, я узнал немного больше об ошибке. В конкретном документе, который вызывает исключение, есть изображения, вставленные в них. Когда я удаляю изображения, исключение не происходит. Возможно, это может быть ошибка DocumentViewer, но я все еще пытаюсь...
Нет, пока ничего.
Просто для перечисления, я пробовал выполнить следующие методы:
Перед удалением файла установите все значение null в событие "Закрыто" в окне. Это включает в себя свойство DocumentViewer.Document и объект DocumentViewer.
Используется ShowDialog(), чтобы открыть окно и установить его значение null после этого. Перемещено удаление файла в событие "Выход" объекта System.Windows.Application, который открывает окно. Все еще выдает исключение, которое используется в файле.
Ошибка DocumentViewer
Я подозреваю, что вы столкнулись с той же проблемой, что и http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic59281.aspx
Звучит как ошибка в DocumentViewer, он должен был выложить вложенные BitmapDecoders на закрытие или загрузку изображения с помощью другого варианта кеширования растрового изображения.