2013-03-15 3 views
1

В Windows8 я пытаюсь использовать GetBasicPropertiesAsync(), чтобы получить размер вновь созданного файла. Иногда, но не всегда (~ 25% времени), этот вызов дает исключение:Почему GetBasicPropertiesAsync() иногда выдает исключение?

"Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))". 

Файл создается с помощью DotNetZip. Я добавляю тысячи файлов в архив, который занимает несколько минут, чтобы запустить:

using (ZipFile zip = new ZipFile()) 
{ 
    zip.AddFile(...); // for thousands of files 
    zip.Save(cr.ArchiveName); 
} 
var storageFile = await subFolder.GetFileAsync(cr.ArchiveName); 
// storageFile is valid at this point 
var basicProperties = await storageFile.GetBasicPropertiesAsync(); // BOOM! 

Несколько по-видимому, случайные вещи, кажется, чтобы уменьшить вероятность возникновения исключения:

  1. Удаление существующей копии cr.ArchiveName перед началом цикла.
  2. Не просмотре каталога с помощью File Explorer

Weird, да? Похоже, это может быть ошибка, связанная с File System Tunneling или, возможно, это внутреннее кэширование, которое DotNetZip выполняет и удерживает на ресурсах (возможно, переименовывает файл TEMP) даже после того, как ZipFile настроен?

+2

E_ACCESSDENIED скорее всего указывает, что файл находится в использовании, хотя, глядя на ваш код, я не уверен, почему. Возможно, вы можете попробовать использовать [Handle] (http://technet.microsoft.com/en-US/sysinternals/bb896655), чтобы помочь вам диагностировать проблему. –

ответ

0

Попытка (безуспешно) ответить на мой вопрос.

Сначала, хотя это была известная проблема, когда DotNetZip держал файлы в файлах до следующей сборки мусора. Я использую SL/WP7 порт DotNetZip из http://slsharpziplib.codeplex.com/ который предположительно не содержит ошибку, установленную этим WorkItem:

http://dotnetzip.codeplex.com/workitem/12727

Но, согласно этой теории, делает:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

должен был обеспечить работу, которой она не занималась.

Далее я попытался использовать ручку, которая не показывала никаких других действий на неисправном StorageFile.

Так что пока я все еще в тупике.

+0

Чтобы сделать реальную коллекцию, вам нужно снова запустить GC.Collect() - после WaitForPendingFinalizers refs все еще не удаляются из кучи. Итак: GC.Collect/GC.Wait/GC.Collect для реального полного GC. –