C # Form.Close vs Form.Dispose

88

Soy nuevo en C # e intenté mirar las publicaciones anteriores pero no encontré una buena respuesta.

En una aplicación de Windows Form de C # con un solo formulario, ¿se usa Form.Close()mejor o Form.Dispose()?

MSDN dice que todos los recursos dentro del objeto están cerrados y el formulario se elimina cuando se invoca un cierre. A pesar de ello, me he encontrado con varios ejemplos en línea que siguen a Dispose en lugar de Close.

¿Tiene uno alguna ventaja sobre el otro? ¿Bajo qué escenarios deberíamos preferir uno sobre el otro?

topgun_ivard
fuente
Pregunta ligeramente diferente, misma respuesta, OMI: es decir, Cerrar y Disponer suelen ser equivalentes, excepto que puede llamar a Cerrar más de una vez.
ChrisW
2
@Chrisw: también puede llamar a Dispose más de una vez.
Henk Holterman
@ChrisW, Dispose también debe estar diseñado para ejecutarse más de una vez. bluebytesoftware.com/blog/…
Steven Evers
Lo que me consiguió tan cerca === disponer en lugar de cerrar == form.Visible = false; Esperaba que cerrar sería un método más suave que desechar.
Pete Kirkham
4
@Pete Kirkham: Si quieres form.Visible = false;puedes llamar form.Hide(). De hecho, form.Hide()simplemente establece this.Visible = false;.
Dirk Vollmar

Respuestas:

171

Este foro en MSDN te lo dice.

Form.Close()envía los mensajes de Windows adecuados para cerrar la ventana de win32. Durante ese proceso, si el formulario no se mostró de forma modal, se llama a Dispose en el formulario. La eliminación del formulario libera los recursos no administrados a los que se aferra el formulario.

Si hace una form1.Show()o Application.Run(new Form1()), se llamará a Dispose cuando Close()se llame.

Sin embargo, si lo hace form1.ShowDialog() para mostrar el formulario de forma modal, el formulario no se eliminará y deberá llamarse a form1.Dispose()sí mismo. Creo que esta es la única vez que debe preocuparse por deshacerse del formulario usted mismo.

Kyra
fuente
¿La 1ª versión incluía la cita? +1 para compensar.
Henk Holterman
@Dan la primera versión apestaba ... (Lo siento @Kyra)
jjnguy
13
Esto no es lo mismo que los estados de MSDN en msdn.microsoft.com/en-us/library/… : "La única condición cuando un formulario no se elimina en Cerrar es cuando es parte de una interfaz de múltiples documentos (MDI) aplicación y el formulario no es visible. En este caso, deberá llamar a Dispose manualmente para marcar todos los controles del formulario para la recolección de basura ". Sin embargo, debería ser fácil comprobar si los formularios modales se eliminan o no con una muestra simple.
Dirk Vollmar
14

Como regla general, siempre recomendaría llamar explícitamente al método Dispose para cualquier clase que lo ofrezca, ya sea llamando al método directamente o envolviéndolo en un bloque "using".

Muy a menudo, las clases que implementan IDisposible lo hacen porque envuelven algún recurso no administrado que debe liberarse. Si bien estas clases deben tener finalizadores que actúen como una protección, llamar a Dispose ayudará a liberar esa memoria antes y con menos gastos generales.

En el caso del objeto Form, como se indica en el enlace de Kyra, el método Close está documentado para invocar Dispose en su nombre, por lo que no es necesario que lo haga explícitamente. Sin embargo, para mí, eso siempre me ha parecido depender de un detalle de implementación. Prefiero llamar siempre tanto a Close como a Dispose para las clases que los implementan, para protegerme de cambios / errores de implementación y por el bien de ser claro. Un método Dispose implementado correctamente debe ser seguro para invocar varias veces.

Jesse Squire
fuente
6

No llamar Closeprobablemente evita el envío de un montón de mensajes Win32 que uno pensaría que son algo importantes, aunque no podría decirle específicamente por qué ...

Closetiene el beneficio de generar eventos (que pueden cancelarse) de modo que un extraño (al formulario) pueda observar FormClosingyFormClosed reaccionar en consecuencia.

No tengo claro si FormClosingy / o FormClosedse plantean si simplemente desechas el formulario, pero te lo dejo para que lo experimentes.

Perro rojo
fuente
2
Si desecha el formulario, los eventos de cierre y cerrados no se llaman.
matriz
4
llamar al método Dispose causaría parpadeo de la ventana cuando se usa en Modal-Form sobre la ventana mdi-child
dotNETbeginner
1

Usar usinges una forma bastante buena:

using (MyForm foo = new MyForm())
{
    if (foo.ShowDialog() == DialogResult.OK)
    {
        // your code
    }
}
Mustafa Burak Kalkan
fuente
0

Cerrar (): el recurso administrado se puede cerrar temporalmente y volver a abrirse.

Dispose (): elimina permanentemente el recurso administrado o no administrado

Yuresh Karunanayake
fuente
3
Esto es cierto solo si el formulario se mostró usando ShowDialog(). De lo contrario, Close()también desechará el formulario.
Peter Duniho
-1

Si usa form.close () en su formulario y establece el Evento FormClosing de su formulario y usa form.close () en este Evento, cae en un bucle ilimitado y se produjo un Argumento fuera del rango y la solución es cambiar el formulario .close () con form.dispose () en caso de FormClosing. Espero que este pequeño consejo te ayude !!!

Hadi Erfanian
fuente
-1

Lo que acabo de experimentar con las herramientas de diagnóstico de VS es que llamé a this.Close () y luego se activó el evento de cierre. Luego, cuando llamo a this.Dispose () al final del evento Formclosing donde elimino muchos otros objetos, limpia todo mucho más suavemente.

smoothumut
fuente