C # Form.Close vs Form.Dispose

88

Eu sou novo no C # e tentei ler as postagens anteriores, mas não encontrei uma boa resposta.

Em um aplicativo C # Windows Form com um único formulário, está usando Form.Close()melhor ou Form.Dispose()?

MSDN diz que todos os recursos dentro do objeto são fechados e o formulário é descartado quando um Close é invocado. Apesar disso, encontrei vários exemplos online que seguem um Dispose em vez de um Close.

Um tem vantagem sobre o outro? Em quais cenários devemos preferir um em vez do outro?

topgun_ivard
fonte
Pergunta ligeiramente diferente, mesma resposta, IMO: ou seja, Fechar e Eliminar são geralmente equivalentes, exceto que você pode chamar Fechar mais de uma vez.
ChrisW
2
@Chrisw: você também pode chamar Dispose mais de uma vez.
Henk Holterman
@ChrisW, Dispose também deve ser projetado para ser executado mais de uma vez. bluebytesoftware.com/blog/…
Steven Evers
O que me deixou tão perto === dispor em vez de fechar == form.Visible = false; Eu esperava que o fechamento fosse um método mais suave do que o descarte.
Pete Kirkham
4
@Pete Kirkham: Se quiser, form.Visible = false;pode ligar form.Hide(). Na verdade, form.Hide()simplesmente define this.Visible = false;.
Dirk Vollmar

Respostas:

172

Este fórum no MSDN informa isso.

Form.Close()envia as mensagens adequadas do Windows para encerrar a janela win32. Durante esse processo, se o formulário não foi mostrado modalmente, Dispose é chamado no formulário. Descartar o formulário libera os recursos não gerenciados que o formulário está mantendo.

Se você fizer um form1.Show()ou Application.Run(new Form1()), Dispose será chamado quando Close()for chamado.

Porém, se você fizer form1.ShowDialog() para mostrar o formulário modalmente, o formulário não será descartado e você precisará ligar para form1.Dispose()si mesmo. Acredito que este seja o único momento em que você deve se preocupar em descartar o formulário sozinho.

Kyra
fonte
A 1ª versão incluiu a citação? +1 para compensar.
Henk Holterman
@Dan a primeira versão foi uma droga ... (Desculpe @Kyra)
jjnguy
13
Isso é um pouco diferente dos estados do MSDN em msdn.microsoft.com/en-us/library/… : "A única condição quando um formulário não é descartado em Fechar é quando ele faz parte de uma interface de documentos múltiplos (MDI) aplicativo, e o formulário não está visível. Nesse caso, você precisará chamar Dispose manualmente para marcar todos os controles do formulário para coleta de lixo. " No entanto, deve ser fácil verificar se os formulários modais são descartados ou não com uma amostra simples.
Dirk Vollmar
15

Como regra geral, eu sempre recomendaria chamar explicitamente o método Dispose para qualquer classe que o oferecesse, seja chamando o método diretamente ou envolvendo um bloco "usando".

Na maioria das vezes, as classes que implementam IDisposible o fazem porque envolvem algum recurso não gerenciado que precisa ser liberado. Embora essas classes devam ter finalizadores que agem como uma proteção, chamar Dispose ajudará a liberar essa memória mais cedo e com menor sobrecarga.

No caso do objeto Form, como o link de Kyra observou, o método Close está documentado para invocar Dispose em seu nome, portanto, você não precisa fazer isso explicitamente. No entanto, para mim, sempre pareceu confiar em um detalhe de implementação. Eu prefiro sempre chamar Close e Dispose para classes que os implementam, para me proteger contra alterações / erros de implementação e para ser claro. Um método Dispose implementado corretamente deve ser seguro para invocar várias vezes.

Jesse Squire
fonte
6

Não ligar Closeprovavelmente ignora o envio de um monte de mensagens Win32 que se poderia pensar que são de alguma forma importantes, embora eu não pudesse dizer especificamente por quê ...

Closetem o benefício de aumentar eventos (que podem ser cancelados) de modo que um estranho (para a forma) possa observar FormClosingeFormClosed reagir de acordo.

Não estou certo se FormClosinge / ou FormClosedsão gerados se você simplesmente descartar o formulário, mas vou deixar isso para você experimentar.

Cachorro vermelho
fonte
3
Se você descartar o formulário, os eventos de fechamento e fechado não serão chamados.
matriz
5
chamar o método Dispose causaria oscilação da janela quando usado no Modal-Form sobre a janela mdi-child
dotNETbeginner
1

Usar usingé uma maneira muito boa:

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

Close () - o recurso gerenciado pode ser fechado temporariamente e pode ser aberto novamente.

Dispose () - remove permanentemente o recurso gerenciado ou não gerenciado

Yuresh Karunanayake
fonte
3
Isso é verdadeiro apenas se o formulário foi mostrado usando ShowDialog(). Caso contrário, Close()descartará o formulário também.
Peter Duniho de
-1

Se você usar form.close () em seu formulário e definir o evento FormClosing do seu formulário e usar form.close () neste evento, você cairá em um loop ilimitado e um argumento fora do intervalo acontecerá e a solução é mudar a forma .close () com form.dispose () em Evento de FormClosing. Espero que essa dica te ajude !!!

Hadi Erfanian
fonte
-1

O que acabei de experimentar com as ferramentas de diagnóstico do VS é que chamei de this.Close () e o evento formclosing foi acionado. Então, quando eu chamo this.Dispose () no final do evento Formclosing, onde disponho muitos outros objetos nele, ele limpa tudo de forma muito mais suave.

Smoothumut
fonte