Странная вещь о функциях перечисления файловой системы .NET 4.0
Я просто прочитал страницу "Whats new.NET Framework 4.0" . Мне трудно понять последний абзац:
Чтобы удалить открытые дескрипторы в перечисленных каталогах или файлах
-
Создайте собственный метод (или функцию в Visual Basic), чтобы содержать ваш код перечисления.
-
Применить атрибут MethodImplAttribute с помощью параметра NoInlining к новому методу. Например:
[MethodImplAttribute(MethodImplOptions.NoInlining)]
Private void Enumerate()
-
Включить следующие вызовы методов для запуска после перечисления код:
* The GC.Collect() method (no parameters).
* The GC.WaitForPendingFinalizers() method.
Почему атрибут NoInlining? Какой вред можно было бы сделать здесь?
Зачем вызывать сборщик мусора вручную, почему бы не сделать, чтобы перечислитель реализовал IDisposable в первую очередь? Я подозреваю, что они используют API-вызовы FindFirstFile()/FindNextFile() API для memlement, поэтому FindClose() нужно вызывать в любом случае, если перечисление выполнено.
EDIT:
У кого-нибудь есть идея, почему в статье предлагается атрибут NoInlining?
Ответы
Ответ 1
Довольно странно. Итератор правильно реализует IDisposable, он вызывает FindClose(). Параметры AllDirectories могут быть источником проблем, поскольку FindFileFirst/Next только позволяет выполнять итерацию одного каталога. Но я вижу, что итератор делает все правильно, он только удерживает один дескриптор открытым при повторении структуры каталогов.
В статье MSDN упоминается "если есть открытый дескриптор, который остается в одной из перечисленных каталогов или файлов". FindFileFirst/Next не оставит ручку открытой. Но неаккуратный код пользователя, который читает файлы при перечислении. "операция удаления в файле или каталоге" тоже актуальна, я думаю, что поведение изменилось в Vista. DeleteFile() может преуспеть, но файл фактически не исчезнет, пока все дескрипторы файла не будут закрыты.
Нам нужен кто-то, кто добровольно и не выполнит этот код на XP. Я считаю, что скоро найдем кого-нибудь:)