2009-07-30 7 views
13

Ho un'applicazione winforms.Winforms inizia con Program.cs dove abbiamo definito main(). Ho inserito questo codice nel blocco try-catch.Perché l'eccezione win32 non viene catturata dal meccanismo di gestione delle eccezioni C#

[STAThread] 
    static void Main() 
    { 
     try 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new frmSplash()); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      if (ex.InnerException != null) 
      { 
       MessageBox.Show(ex.InnerException.ToString()); 
      } 
     } 
    } 

Ogni volta che c'è un'eccezione win32, questo meccanismo fallisce e il messaggio di eccezione non gestita viene gettato e crash dell'applicazione.
Ho 2 domande riguardanti questo codice:

1) Perché le eccezioni di win32 non vengono catturate.

2) È buona norma rilevare le eccezioni al massimo livello.

+0

Wow, non ho mai veramente pensato a questo, buona domanda e buone risposte :) – leppie

+0

Si prega di commentare anche la seconda domanda. – Rohit

+0

Forse potresti fare una seconda domanda SO ;-) – Mac

risposta

12

EDIT: come Pratik sottolineato, la seguente risposta si applica solo a .NET 1.0 e .NET 1.1. A partire da .NET 2.0, l'eccezione non CLS dovrebbe essere rilevata come RuntimeWrappedException.


Perché le eccezioni Win32 non derivano dalla classe .NET Exception. Prova:

try { 
} catch (Exception ex) { 
    // .NET exception 
} catch { 
    // native exception 
} 

Vedi Catch non-CLSCompliant exceptions in general handlers per ulteriori informazioni.

+4

Questo non è richiesto in .Net 2.0 per impostazione predefinita. Tutte le eccezioni non CLS sono rapped come RuntimeWrappedException. Vedere http://msdn.microsoft.com/en-us/library/ms404228.aspx – softveda

+0

Win32Exception

+0

@Pratik: grazie per il collegamento. @ Tommy Carlier: cf. Link di Pratik ... – Mac

0

Potrebbe essere necessario prendere come Win32Exception (o ExternalException) invece

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

Mi pare di ricordare che Win32Exception eredita da ExternalException ma ExternalException non eredita da Exception in modo da non essere catturati dal codice .

Modifica: Vedere altre risposte per perché questo è sbagliato!

Edit 2: Per quanto riguarda la seconda parte, come affermato da AnthonyWJones E 'di buone maniere per consentire all'utente di sapere che un problema ha causato l'applicazione per chiudere, ma mi consiglia di utilizzare una dichiarazione inglese semplice per l'utente e registrando lo stack delle eccezioni in un file di registro per uso personale.

+1

Entrambe sono derivate da Eccezione, quindi sulla superficie di esso il fermo nella domanda dovrebbe funzionare. Per il motivo per cui non è vedere la mia risposta. – AnthonyWJones

3

L'esecuzione di Application.Run non genera un errore. Questo sta accadendo su un altro thread (o almeno in modo asincrono).

È una buona idea informare l'utente in modo amichevole che l'applicazione ha fallito prima che scompaia completamente, tuttavia non è una buona idea catturarla e poi continuare.

3

Mentre non so perché il blocco di cattura non funziona provare a utilizzare il Application ThreadException Event. Ciò dovrebbe rilevare qualsiasi errore nei thread dell'applicazione. Aggiungi un gestore di eventi prima di chiamare Application.Run.

Per la tua seconda risposta sicuramente si. Sviluppo e gestisco un'applicazione winform aziendale che parla con un backend del servizio Web su thread in background. Se una chiamata a un servizio web si blocca, l'evento di threadexception dell'applicazione (e anche un'appledain unhandledexception) gestisce, registra e visualizza un errore che gli utenti aziendali possono segnalare e consentire loro di continuare senza arrestare l'applicazione.

0

1) Le eccezioni Win32 devono essere rilevate. Forse l'eccezione viene generata da un thread in background o dal thread GC?

2) Dipende dalla struttura dell'app. Ad esempio, se la tua UI di notifica degli errori fosse legata al modulo principale in qualche modo (ad esempio, è necessario richiamare il thread dell'interfaccia utente da un thread di lavoro), sarebbe stupido visualizzare un'interfaccia utente in un blocco di codice all'esterno del codice che esegue il messaggio ciclo continuo. Tuttavia, se il tuo esempio di codice è single-thread, allora andrebbe bene.

1

Prova la sottoscrizione di questi eventi prima che l'applicazione si avvia (Application.Run):

Si potrebbe quindi eliminare il blocco try catch.


penso che sia cattiva pratica di intercettare le eccezioni al più alto livello, ma non si può evitare! Durante lo sviluppo (Debug), queste eccezioni non dovrebbero essere catturate e l'applicazione dovrebbe fare la cosa più brutta possibile (crash?). In produzione (versione), è consigliabile che la tua applicazione si degradi nel modo migliore possibile anche quando si verificano eccezioni non gestite. Questo è uno dei pochi usi che ho trovato per lo DEBUG preprocessor variable.

+0

Ecco qua: 2 risposte in una. A quale hai intenzione di (o contro)? – Mac

Problemi correlati