2010-04-18 4 views
15

Acabo de leer una página de "Whats new .NET Framework 4.0". Tengo problemas para entender el último párrafo:Algo extraño acerca de la funcionalidad de enumeración del sistema de archivos .NET 4.0

Para eliminar los identificadores abiertos en los directorios o archivos

  1. Crear un método personalizado (o función en Visual Basic) para contener su código de enumeración enumerados.

  2. Aplicar el atributo MethodImplAttribute con la opción NoInlining al nuevo método. Por ejemplo:

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

  3. Incluir las siguientes llamadas a métodos, a correr detrás de su código de enumeración :

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

Por qué el atributo NoInlining? ¿Qué daño haría la línea interna aquí?

¿Por qué llamar al recolector de basura manualmente? ¿Por qué no hacer que el enumerador implemente IDisposable en primer lugar? Sospecho que utilizan las llamadas API FindFirstFile()/FindNextFile() para la imlementación, por lo que se debe llamar a FindClose() en cualquier caso si la enumeración está completa.

EDIT:

¿Alguien tiene una idea de por qué el atributo NoInlining se sugiere en el artículo?

+4

Wow. No esperaba ver * que * en el consejo de MSDN ... –

+0

Estoy sorprendido de ver eso también, pero tenga en cuenta las circunstancias especiales descritas en el artículo: "Si está ejecutando Windows XP o una versión anterior, una eliminación la operación en un archivo o directorio que sigue a una enumeración podría fallar si hay un identificador abierto que permanece en uno de los directorios o archivos enumerados. Si esto ocurre, debe inducir a una recolección de elementos no utilizados para eliminar los identificadores abiertos ". –

+0

@Brian: si solo se aplica a XP, estoy contento ... ish. –

Respuesta

4

Bastante extraño. El iterador implementa correctamente IDisposable, llama a FindClose(). Las opciones de AllDirectories podrían ser una fuente de problemas ya que FindFileFirst/Next solo permite iterar un único directorio. Pero veo que el iterador está haciendo lo correcto, solo mantiene abierto un único identificador mientras itera la estructura del directorio.

El artículo de MSDN menciona específicamente "si hay un controlador abierto que permanece en uno de los directorios o archivos enumerados". FindFileFirst/Next no dejará un identificador abierto. Pero el código de usuario descuidado que lee archivos mientras enumera lo hace. "una operación de eliminación en un archivo o directorio" también es relevante, creo que el comportamiento cambió en Vista. Un DeleteFile() puede tener éxito, pero el archivo no desaparecerá realmente hasta que se cierren todos los identificadores del archivo.

Necesitamos a alguien para ser voluntario y no implementar este código en XP. Creo que pronto encontraremos a alguien :)

Cuestiones relacionadas