2010-06-30 16 views
10

Estoy haciendo algo de desarrollo de ASP.NET en VS y acabo de encontrar una pequeña sugerencia de código interesante (creo que provienen de coderush pero podría estar equivocado).¿Por qué tendría que llamar a disponer de controles ASP.NET?

Cada vez que estoy creando controles, me dice que debería usar una declaración "using" para ellos. Aunque estoy un poco confundido sobre lo que está pasando aquí. con el uso de mi código es algo como:

using (HtmlTableRow tableRow = new HtmlTableRow()) 
{ 
    tableRow.Attributes.Add("class", isOddRow ? "OddRow" : "EvenRow"); 
    listingTable.Rows.Add(tableRow); 
    addCell(tableRow, row, "issueId"); 
    addCell(tableRow, row, "Title"); 
    addCell(tableRow, row, "Type"); 
    addCell(tableRow, row, "Summary"); 
} 

Así que espero que al final de la instrucción using llamará a disponer en el TableRow. Sin embargo, los documentos en la biblioteca de MSDN dicen:

El método Dispose deja el control en un estado inutilizable. Después de llamar al este método, debe liberar todas las referencias del control para que la memoria que estaba ocupando pueda ser reclamada por la recolección de elementos no utilizados.

Así que esperaría que ahora tengo un objeto inutilizable en mi estructura de control por lo que se rompería o no se renderizaría o algo así. Sin embargo, todo parece funcionar bien.

Entonces, ¿qué me pregunto es por qué todos los controles son desechables? ¿Es solo porque algunos de ellos serán y todos desechables significa que una llamada para deshacerse en el nivel superior se puede pasar a todos los controles secundarios recursivamente?

Creo que lo entendería si no fuera por el hecho de que los documentos dicen explícitamente que deshacerse de un control lo hace inutilizable ... ¿Están los documentos simplemente equivocados?

+0

¿Cómo podemos manejar los objetos huérfanos (que @Toby mencionó) si no estamos usando el bloque "usar"? – Lijo

Respuesta

14

No deberías hacer esto. Lo que debe hacer es asegurarse de que listingTable esté en la colección Controls para que se elimine cuando se elimine la página. El objeto listingTable es el responsable de desechar correctamente todos sus hijos.

Por eso todos los objetos Control implementan la interfaz IDisposable. De esta forma, cada control padre puede llamar al Dispose en todos sus hijos sin primero tener que probar/emitir cada uno. Cada control es individualmente responsable de determinar si realmente tiene algo que debe limpiarse cuando se llama al método Dispose.

Los documentos no son incorrectos. Cualquier objeto escrito correctamente que implemente IDisposable y tenga datos de estado que estén realmente limpios durante el proceso de eliminación debe arrojar una ObjectDisposedException si se accede a cualquiera de sus propiedades o métodos públicos/protegidos/internos después de haber sido eliminados. (Suponga que el estado no es válido después de haber llamado al Dispose). Algunos tipos ignorarán esta regla si no tienen nada que limpiar, y no tienen que preocuparse por el estado no válido.

La razón por la que está recibiendo una sugerencia para envolverlo en un bloque using es debido a que el analizador no se da cuenta de que listingTable dispondrá su colección Rows, que dispondrá cada uno de los objetos de fila que se han añadido a la misma. Además, si se lanza una excepción entre HtmlTableRow tableRow = new HtmlTableRow() y listingTable.Rows.Add(tableRow), el objeto HtmlTableRow será 'huérfano' y no estará en la jerarquía IDisposable de ningún otro objeto. Code Analysis desea que use un bloque try/finally para deshacerse inmediatamente del HtmlTableRow si esto sucede.

+1

Gracias. Yo tenía una sospecha sobre la mayor parte de eso, pero es bueno obtener un poco más de detalle sobre lo que está sucediendo aquí. Ni siquiera había considerado la "huérfana" del control. – Chris

+0

¿Cómo podemos manejar los objetos 'huérfanos' si no estamos usando el bloque" usar "? – Lijo

+0

@Lijo: utilice un bloque try/finally – Toby

Cuestiones relacionadas