que - C#: ¿Hay una ventaja para desechar recursos en orden inverso de su asignación?
programa en c# (5)
Los ''usos'' anidados muestran que ''sobrevivido'' no está realmente encendido, y raramente lo es (no ir y decir nunca después de 40 años de evidencia) ... Y eso incluye la máquina virtual basada en pila que se ejecuta en, por ejemplo, CMOS.
[A pesar de algunos intentos de MSDN.com y Duffius para hacer que desaparezca, usted sabe administrarlo todo para usted la diferencia entre el montón y la pila. Qué idea tan inteligente ... en el espacio]
Hace muchos años, se me advirtió que, siempre que sea posible, liberara los recursos en orden inverso a cómo se asignaron. Es decir:
block1 = malloc( ... );
block2 = malloc( ... );
... do stuff ...
free( block2 );
free( block1 );
Me imagino que en una máquina MS-DOS de 640 K, esto podría minimizar la fragmentación del montón. ¿Hay alguna ventaja práctica de hacer esto en una aplicación C # /.NET, o es este un hábito que ha sobrevivido a su relevancia?
No te molestes GarbageCollector se reserva el derecho de desfragmentar y mover objetos en el montón, por lo que no se sabe en qué orden están las cosas.
Además, si está eliminando las referencias B de A y B, no debería importar si A dispone de B cuando descarta A, ya que el método Dispose debería llamarse más de una vez sin que se produzca una excepción.
Si se refiere a la hora en que se llama al destructor en los objetos, entonces el recolector de elementos no utilizados tiene una influencia muy pequeña sobre la destrucción y es explícitamente no determinista de acuerdo con la definición del lenguaje.
Si se refiere a llamar a IDisposable.Dispose (), eso depende del comportamiento de los objetos que implementan la interfaz IDisposable.
En general, el orden no importa para la mayoría de los objetos del Marco, excepto en la medida en que sea importante para el código de llamada. Pero si el objeto A mantiene una dependencia en el objeto B, y el objeto B está dispuesto, entonces bien podría ser importante no hacer ciertas cosas con el objeto A.
En la mayoría de los casos, Dispose () no se llama directamente, sino que se llama implícitamente como parte de una instrucción using o foreach, en cuyo caso el patrón de orden inverso surgirá de forma natural, de acuerdo con la incrustación de la declaración.
using(Foo foo = new Foo())
using(FooDoodler fooDoodler = new FooDoodler(foo))
{
// do stuff
// ...
// fooDoodler automatically gets disposed before foo at the end of the using statement.
}
Si sus recursos se crean bien, esto no debería importar (mucho).
Sin embargo, muchas bibliotecas mal creadas no hacen la verificación adecuada. La eliminación de los recursos a la inversa de su asignación generalmente significa que usted está eliminando recursos dependientes de otros recursos primero, lo que puede evitar que las bibliotecas mal escritas causen problemas. (Nunca descarta un recurso, luego use uno que dependa de la existencia del primero en este caso).
También es una buena práctica, ya que no va a deshacerse accidentalmente de un recurso requerido por otro objeto demasiado pronto.
Aquí hay un ejemplo: mira una operación de base de datos. No desea cerrar / eliminar su conexión antes de cerrar / eliminar su comando (que usa la conexión).
"El tiempo de ejecución no garantiza el orden en que se invocan los métodos de Finalización. Por ejemplo, digamos que hay un objeto que contiene un puntero a un objeto interno. El recolector de basura ha detectado que ambos objetos son basura. , diga que el método Finalize del objeto interno se llama primero. Ahora, el método Finalize del objeto externo tiene permiso para acceder al objeto interno y llamar a métodos, pero el objeto interno se ha finalizado y los resultados pueden ser impredecibles. Por esta razón, se recomienda encarecidamente que los métodos Finalize no accedan a ningún objeto miembro interno ".
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
Así que puede preocuparse por su LIFO disponer de la semántica tanto como desee, pero si pierde una, los Dispose () se llamarán en el orden que desee CLR.
(Esto es más o menos lo que dijo Will, arriba)