C # Form.Close vs Form.Dispose


88

Sono nuovo in C # e ho provato a guardare i post precedenti ma non ho trovato una buona risposta.

In un'applicazione Windows Form C # con un singolo modulo, si usa Form.Close()meglio o Form.Dispose()?

MSDN dice che tutte le risorse all'interno dell'oggetto vengono chiuse e il modulo viene eliminato quando viene richiamato un Close. Nonostante ciò, mi sono imbattuto in diversi esempi online che seguono un Dispose piuttosto che un Close.

Uno ha un vantaggio sull'altro? In quali scenari dovremmo preferire uno rispetto all'altro?


Domanda leggermente diversa, stessa risposta, IMO: cioè Close e Dispose sono generalmente equivalenti, tranne per il fatto che puoi chiamare Close più di una volta.
ChrisW

2
@ Chrisw: puoi anche chiamare Dispose più di una volta.
Henk Holterman,

@ ChrisW, anche Dispose dovrebbe essere progettato per essere eseguito più di una volta. bluebytesoftware.com/blog/…
Steven Evers

La cosa che mi ha fatto chiudere === disporre invece di chiudere == form.Visible = false; Mi aspettavo che chiudere sarebbe stato un metodo più morbido rispetto allo smaltimento.
Pete Kirkham

4
@ Pete Kirkham: se vuoi form.Visible = false;puoi chiamare form.Hide(). In effetti, form.Hide()semplicemente imposta this.Visible = false;.
Dirk Vollmar

Risposte:


172

Questo forum su MSDN te lo dice.

Form.Close()invia i messaggi di Windows appropriati per chiudere la finestra win32. Durante quel processo, se il modulo non è stato visualizzato in modo modale, Dispose viene chiamato nel modulo. L'eliminazione del modulo consente di liberare le risorse non gestite a cui il modulo tiene.

Se fai un form1.Show()o Application.Run(new Form1()), Dispose verrà chiamato quando Close()viene chiamato.

Tuttavia, se si form1.ShowDialog() mostra il modulo in modo modale, il modulo non verrà eliminato e sarà necessario chiamare form1.Dispose()te stesso. Credo che questa sia l'unica volta in cui dovresti preoccuparti di smaltire il modulo da solo.


La prima versione includeva la citazione? +1 per compensare.
Henk Holterman

@ Dan la prima versione ha fatto schifo ... (Sorry @Kyra)
jjnguy

13
Questo non è in qualche modo lo stesso degli stati MSDN su msdn.microsoft.com/en-us/library/… : "L'unica condizione in cui un modulo non viene eliminato in Close è quando fa parte di un'interfaccia a più documenti (MDI) l'applicazione e il modulo non è visibile. In questo caso, sarà necessario chiamare Dispose manualmente per contrassegnare tutti i controlli del modulo per la garbage collection. " Tuttavia, dovrebbe essere facile controllare se i moduli modali vengono eliminati o meno con un semplice campione.
Dirk Vollmar


15

Come regola generale, raccomanderei sempre di chiamare esplicitamente il metodo Dispose per qualsiasi classe che lo offre, chiamando il metodo direttamente o inserendo un blocco "using".

Molto spesso, le classi che implementano IDisposible lo fanno perché racchiudono una risorsa non gestita che deve essere liberata. Sebbene queste classi dovrebbero avere finalizzatori che fungono da salvaguardia, la chiamata a Dispose consentirà di liberare quella memoria prima e con un sovraccarico inferiore.

Nel caso dell'oggetto Form, come notato dal collegamento di Kyra, il metodo Close è documentato per richiamare Dispose per tuo conto, quindi non è necessario farlo esplicitamente. Tuttavia, per me, è sempre stato come fare affidamento su un dettaglio di implementazione. Preferisco chiamare sempre sia Close che Dispose per le classi che li implementano, per proteggersi da modifiche / errori di implementazione e per motivi di chiarezza. Un metodo Dispose implementato correttamente dovrebbe essere sicuro da invocare più volte.



6

La mancata chiamata Closeprobabilmente evita l'invio di un mucchio di messaggi Win32 che si potrebbe pensare siano in qualche modo importanti anche se non potrei dirti specificamente perché ...

Closeha il vantaggio di generare eventi (che possono essere annullati) in modo tale che un estraneo (al modulo) possa guardare FormClosinge FormClosedper reagire di conseguenza.

Non è chiaro se FormClosinge / o FormClosedvengono sollevati se getti semplicemente il modulo, ma lo lascio a te per sperimentare.


3
Se si elimina il modulo, gli eventi di chiusura e di chiusura non vengono chiamati.
matrice

5
la chiamata al metodo Dispose causerebbe lo sfarfallio della finestra se utilizzata su Modal-Form sulla finestra mdi-child
dotNETbeginner

1

L'utilizzo usingè un modo abbastanza buono:

using (MyForm foo = new MyForm())
{
    if (foo.ShowDialog() == DialogResult.OK)
    {
        // your code
    }
}

0

Close (): la risorsa gestita può essere temporaneamente chiusa e può essere riaperta.

Dispose (): rimuove in modo permanente la risorsa gestita o non gestita


3
Ciò è vero solo se il modulo è stato mostrato utilizzando ShowDialog(). In caso contrario, Close()eliminerà anche il modulo.
Peter Duniho

-1

Se usi form.close () nel tuo modulo e imposti l'evento FormClosing del tuo modulo e usi form.close () in questo evento, cadi in un ciclo illimitato e Argomento fuori intervallo è accaduto e la soluzione è che cambia il modulo .close () con form.dispose () in caso di chiusura del modulo. Spero che questo piccolo consiglio ti aiuti !!!


-1

Quello che ho appena sperimentato con gli strumenti diagnostici VS è che ho chiamato this.Close () quindi si è verificato l'evento di chiusura del modulo. Quindi quando chiamo this.Dispose () alla fine dell'evento Formclosing in cui dispongo molti altri oggetti, pulisce tutto in modo molto più fluido.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.