16

I just read a page of "Whats new .NET Framework 4.0". I have trouble understanding the last paragraph:

To remove open handles on enumerated directories or files

  1. Create a custom method (or function in Visual Basic) to contain your enumeration code.

  2. Apply the MethodImplAttribute attribute with the NoInlining option to the new method. For example:

    [MethodImplAttribute(MethodImplOptions.NoInlining)] Private void Enumerate()

  3. Include the following method calls, to run after your enumeration code:

      * The GC.Collect() method (no parameters).
      * The GC.WaitForPendingFinalizers() method.
    

Why the attribute NoInlining? What harm would inlining do here?

Why call the garbage collector manually, why not making the enumerator implement IDisposable in the first place? I suspect they use FindFirstFile()/FindNextFile() API calls for the imlementation, so FindClose() has to be called in any case if the enumeration is done.

EDIT:

Does anybody have an idea why the NoInlining attribute is suggested in the article?

codymanix
  • 28,510
  • 21
  • 92
  • 151
  • 4
    Wow. I didn't expect to see *that* in MSDN advice... – Marc Gravell Apr 18 '10 at 19:34
  • I'm surprised to see that as well, but do note the special circumstances outlined in the article: "If you are running Windows XP or earlier, a delete operation on a file or directory that follows an enumeration could fail if there is an open handle that remains on one of the enumerated directories or files. If this is occurring, you must induce a garbage collection to remove the open handles." – Brian Rasmussen Apr 18 '10 at 19:44
  • @Brian - if it only applies to XP I'm content...ish. – Marc Gravell Apr 18 '10 at 19:59

1 Answers1

4

Pretty bizarre. The iterator correctly implements IDisposable, it calls FindClose(). The AllDirectories options could be a source of trouble since FindFileFirst/Next only allows iterating a single directory. But I'm seeing the iterator doing the right thing, it only keeps a single handle open while iterating the directory structure.

The MSDN article specifically mentions "if there is an open handle that remains on one of the enumerated directories or files". FindFileFirst/Next won't leave a handle open. But sloppy user code that reads files while enumerating does. "a delete operation on a file or directory" is relevant too, I think the behavior changed in Vista. A DeleteFile() can succeed but the file won't actually disappear until all handles on the file are closed.

We need somebody to volunteer and not implement this code on XP. I reckon we'll find someone soon :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536