Deseche el formulario después del cierre
Tengo el nuevo problema al abrir y cerrar formularios en C#.
Mi problema es cómo desechar el formulario después del cierre.
aquí está mi código:
Programa.cs:
static class Program
{
public static Timer timer;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
timer = new Timer { Interval = 1000};
timer.Start();
Application.Run(new Form1());
}
}
Formulario1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
/// I've tried Dispose() method . but didn't work
}
}
Formulario2.cs:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
Program.timer.Tick += timer_Tick;
Close();
// I've tried Dispose() method instead of Close() but didn't work
}
private int count = 0;
void timer_Tick(object sender, EventArgs e)
{
count++;
if (count == 5) MessageBox.Show("");
}
}
Editado: Mi pregunta es: ¿por qué el cuadro de mensaje se muestra después de 5 segundos cuando el formulario 2 se ha cerrado?
Esta pregunta resulta ser sobre Dispose.
En primer lugar, Dispose no tiene nada que ver con la recolección de basura. Sucede lo siguiente:
- Tienes una instancia de temporizador global
- Creas formulario2
- Form2 se suscribe al temporizador
- Form2 está cerrado y/o eliminado
- El evento Timer se activa, incrementa el contador y muestra un cuadro de mensaje.
- El evento del temporizador sigue funcionando hasta que se cierra la aplicación.
El punto principal a entender es que Cerrar/Desechar solo cambia el estado del Formulario, no (no pueden) "eliminar" la instancia. Entonces el formulario (cerrado) está ahí, el campo del contador todavía está ahí y el evento se activa.
Bien, parte 1:
Un using () {}
bloque sería mejor pero esto debería funcionar:
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
/// I've tried Dispose() method . but didn't work
form.Dispose(); // should work
}
En caso contrario, describa "no funciona".
private void Form2_Load(object sender, EventArgs e)
{
Program.timer.Tick += timer_Tick;
Close();
/// I've tried Dispose() method instead of Close() . but didn't work
}
Esto es extraño, pero asumiré que es un código artificial para la pregunta.
Su Program.Timer global ahora almacena una referencia a su instancia de Form2 y evitará que se recopile. No impide que se elimine/cierre, por lo que su temporizador seguirá funcionando para un formulario cerrado, y eso generalmente fallará y causará otros problemas.
- No hagas esto (dale a Form2 su propio temporizador)
- Utilice un evento FormClosed para cancelar la suscripción:
Program.timer.Tick -= timer_Tick;
La forma más sencilla y confiable de eliminar el Form
uso posterior es colocar el uso dentro de un bloque de uso.
using (Form2 form = new Form2()) {
form.ShowDialog();
}
El bloque de uso en C# es una construcción que esencialmente expande lo anterior al siguiente código.
Form2 form;
try {
form = new Form2();
...
} finally {
if ( form != null ) {
form.Dispose();
}
}