2010-08-27 16 views
13

Fondamentalmente ho un modulo principale che al momento del caricamento apre un modulo figlio per l'accesso dell'utente. Quando annullano o chiudono questo modulo di accesso, devo chiudere l'intera applicazione.Qual è la differenza tra questi metodi per chiudere la mia domanda?

Ma sembra che ci sia un paio di modi diversi per chiudere un programma C#:

  1. Application.Exit();

  2. Application.ExitThread();

  3. Environment.Exit(1);

  4. Process.GetCurrentProcess().Kill();

  5. SFTPClient.LDAPLoggedIn = false; Close();

EDIT: Scusate se questo non è chiaro: si imposta una proprietà in un oggetto di controllo per indicare che l'accesso non è riuscito. Dopo aver aperto il modulo figlio, vorrei controllare questa proprietà nel modulo padre per vedere se il programma dovrebbe continuare o meno. In pratica sposta la responsabilità di uscire dal programma verso il genitore senza eccezioni.

6: throw new Exception("User closed the form");

Posso vedere che ci sono due modi di gestirlo:

  • Informare il genitore che qualcosa è andato storto (come in 5 e 6.)
  • chiusura del programma dal modulo figlio.

L'una o l'altra di queste due è considerata una pratica migliore?

Ogni approccio sembra avere lo stesso effetto sul mio programma ma come si confronta effettivamente?

UPDATE: Grazie per le risposte. Per coloro che cercano a questa domanda in futuro le persone e curiosi, questa è stata la mia soluzione, alla fine:

private void FormMain_Load(object sender, EventArgs e) 
{ 
    if (new FormLogin().ShowDialog(this) == DialogResult.Cancel) Close(); 
} 

e:

private void buttonCancel_Click(object sender, EventArgs e) 
{ 
    Close(); 
} 

ho scoperto che quando un form viene chiuso tramite clic sulla 'X' , DialogResult è impostato su Annulla automaticamente, quindi tutto ciò che devo fare è Close()

risposta

12

Se si vogliono gestire correttamente l'eccezione in quest'ultimo caso, che è ok (non eccezionale però) - il più a lungo è che è una situazione eccezionale per la vostra applicazione. Altrimenti creerei un nuovo metodo che mostra il modulo come una finestra di dialogo con un booleano.Se il valore booleano torna falso (ovvero, l'utente chiude il modulo), quindi gestisco l'applicazione chiusa da lì (utilizzando Application.Exit()).

È, secondo il mio modesto parere, una pessima pratica chiudere l'applicazione da un bambino piuttosto che dire al genitore. L'unica volta che sono d'accordo con questo è in una situazione FailFast, che sono molto rari.


Questo metodo interrompe tutti messaggio esecuzione loop su tutte le filettature e chiude tutte le finestre dell'applicazione. Questo metodo non forza l'uscita dell'applicazione. Il metodo Exit viene in genere richiamato da un loop di messaggi e forza Esegui per tornare. Per uscire da un loop di messaggi solo per il thread corrente, chiama ExitThread.

Vedi sopra.


Termina questo processo e dà il sistema operativo sottostante il codice di uscita specificato.


Uccidi impone una terminazione del processo, mentre CloseMainWindow richiede solo una terminazione. Quando un processo con un'interfaccia grafica è in esecuzione, il suo ciclo di messaggi è in uno stato di attesa. Il ciclo dei messaggi viene eseguito ogni volta che un messaggio Windows viene inviato al processo dal sistema operativo.


  • SFTPClient.LDAPLoggedIn = false; Close();

Dopo il chiarimento nel commento (passa rifluire al genitore e maniglie da lì), questo è di gran lunga il miglior modo di fare questo.


  • throw new Exception("User closed the form");

genera un'eccezione al processo chiamante. Se questo è il thread principale, genererà l'eccezione in modo molto brutto.

+1

Mi dispiace - per chiarire # 5. Imposta una proprietà in un oggetto controller per indicare che l'accesso non è riuscito. Dopo aver aperto il modulo figlio, vorrei controllare questa proprietà nel modulo padre per vedere se il programma dovrebbe continuare o meno. In pratica sposta la responsabilità di uscire dal programma verso il genitore senza eccezioni. – Nobody

+0

@ rmx - DEFINITAMENTE # 5 quindi, senza dubbio. –

2

È necessario utilizzare Form.Close() anziché Application.Exit. Come nota la documentazione MSDN, eventi come Form.Close e Form.Closing non vengono attivati ​​quando si utilizza Application.Exit.

+0

OK, posso vedere il vantaggio di questo. Quindi dovrebbe essere chiamato 'Application.Exit' da Program.cs dopo che ogni form è stato' Close' d? – Nobody

+0

Nessun motivo per. Il tuo processo terminerà se hai terminato i thread figli e la funzione principale ritorna (terminando il thread principale). Se si desidera fornire un codice di ritorno che potrebbe essere di interesse per il processo che ha avviato il proprio, utilizzare 'Environment.Exit (retcode)' alla fine della funzione principale. –

4

Tutti questi modi per terminare l'applicazione sono troppo complessi e sono utili in diversi scenari, ma non nel tuo.

È possibile riprogettare leggermente l'applicazione per risolvere il problema in modo più elegante. Nel metodo principale è possibile visualizzare il modulo di accesso e se gli utenti fanno clic sul pulsante "Annulla", quindi si esce semplicemente dal metodo principale.Altrimenti ti mostri il modulo principale:

class Program { 
    static void Main(String[] args) { 
    if (Login.Show()) { 
     //Show main form for your application 
    } 
    //otherwise you simply return from Main method 
    } 
} 

Questo comportamento è più chiaro e semplice. E nella maggior parte dei casi la forma principale è troppo alta, quindi il tuo utente dovrebbe aspettare più tempo per vedere la prima finestra dalla tua app.

+0

+1 Quasi esattamente quello che sto dicendo, con il codice. –

1

Grazie OP per la soluzione, volevo solo aggiungervi.

di chiudere il form figlio e tornare qualcosa di diverso Annulla per il genitore:

this.DialogResult = DialogResult.OK; 
this.Close(); 
Problemi correlati