1

In Windows8, I'm trying to use GetBasicPropertiesAsync() to get the size of a newly created file. Sometimes, but not always (~25% of the time), this call gives an exception of:

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

The file is created using DotNetZip. I'm adding thousands of files to the archive which takes a few minutes to run:

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!

A few apparently random things seem to decrease the likelihood of the exception:

  1. Deleting an existing copy of cr.ArchiveName before the start of the loop.
  2. Not viewing the directory using File Explorer

Weird, huh? It smells like it might be a bug related to File System Tunneling or maybe it's some internal caching that DotNetZip is performing and holding onto resources (maybe renaming the TEMP file) even after the ZipFile is disposed?

Community
  • 1
  • 1
Jay Borseth
  • 1,894
  • 20
  • 29
  • 2
    E_ACCESSDENIED most likely indicates the file being in use, although looking at your code I'm not sure why. Maybe you could try using [Handle](http://technet.microsoft.com/en-US/sysinternals/bb896655) to help you diagnose the problem. – Damir Arh Mar 15 '13 at 05:41

1 Answers1

0

Trying to (unsuccessfully) answer my own question.

At first, I though this was a known issue with DotNetZip holding onto file handles until the next garbage collection. I am using the SL/WP7 port of DotNetZip from http://slsharpziplib.codeplex.com/ which presumably doesn't include the bug fixed by this workitem:

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

But, according to that theory, doing:

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

should have provided a work around, which it didn't.

Next I tried using handle, which didn't show any other activity on the failing StorageFile.

So for now, I'm still stumped.

Jay Borseth
  • 1,894
  • 20
  • 29
  • To do a real collection, you need to run GC.Collect() again - after WaitForPendingFinalizers, the refs are still not cleared from the heap. So: GC.Collect/GC.Wait/GC.Collect for a real full GC. – Shahar Prish Jun 05 '16 at 09:52