WPF DocumentViewer не выпускает файл XPS
-
08-07-2019 - |
Вопрос
Я работаю над приложением 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 членом, затем не вызывайте close() для него :)
Другие советы
Вам необходимо закрыть System.IO.Packaging.Пакет, из которого был открыт XpsDocument, назначенный программе просмотра.Кроме того, если вы хотите иметь возможность снова открыть тот же файл в рамках того же сеанса приложения, вам придется удалить Пакет из хранилища пакетов.
Попробуй
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, но я все еще пытаюсь...
Нет, пока по-прежнему ничего.
Просто чтобы перечислить, я попробовал следующие методы, которые не увенчались успехом:
Установите для всего значение null в событии "Закрыто" окна перед удалением файла.Это включает в себя DocumentViewer.Свойство Document и объект DocumentViewer.
Использовал ShowDialog(), чтобы открыть окно и впоследствии присвоить ему значение null.Переместил удаление файла в событие "Выход" системы.Windows.Объект приложения, который открывает окно.По-прежнему выдает исключение о том, что файл используется.
Ошибка DocumentViewer???
Я подозреваю, что вы столкнулись с той же проблемой, что и http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic59281.aspx
Звучит как ошибка в DocumentViewer, он должен был удалить вложенные BitmapDecoders при закрытии или загрузить изображение с другим параметром кэширования bitmap.