Domanda

Da quando Microsoft ha introdotto i blocchi dell'applicazione, ho incontrato persone che usano Blocco applicazione gestione eccezioni . Di recente ho avuto uno sguardo più attento e riassumerei le funzionalità di base come segue (salta il seguente blocco se sai già cosa fa):

  

Il blocco dell'applicazione di gestione delle eccezioni mira a centralizzare e rendere completamente configurabile con i file di configurazione il seguente principali attività di gestione delle eccezioni :

     
      
  • Registrazione di un'eccezione
  •   
  • Sostituzione di un'eccezione
  •   
  • Avvolgimento di un'eccezione
  •   
  • Propagare un'eccezione
  •   
  • ecc.
  •   
     

La libreria lo fa modificando il blocco catch come segue:

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}
     

Basato su quanto specificato in app.config per il nome della politica ( vedi qui per documenti ), HandleException o ...

     
      
  • genera un'eccezione completamente nuova (sostituisce l'eccezione originale)
  •   
  • racchiudi l'eccezione originale in una nuova e lancia
  •   
  • ingoia l'eccezione (ovvero non fa nulla)
  •   
  • hai ricodificato l'eccezione originale
  •   
     

Inoltre puoi anche configurarlo per fare più cose in anticipo (ad es. registrare l'eccezione).

Ora ecco il mio problema: non riesco completamente a vedere come può essere utile renderlo configurabile se un'eccezione viene sostituita, spostata, ingoiata o riproposta. Nella mia esperienza, questa decisione deve essere presa nel momento in cui scrivi il codice perché in genere dovrai cambiare il codice circostante o chiamante quando cambi il comportamento di gestione delle eccezioni.

Ad esempio, è probabile che il codice inizi a comportarsi in modo errato quando si riconfigura in modo tale che una particolare eccezione generata in un determinato punto venga ingoiata invece di essere riproposta (potrebbe esserci del codice dopo il blocco catch che non deve essere eseguito quando l'eccezione si verifica). Lo stesso vale per tutte le altre possibili modifiche nella gestione delle eccezioni (ad esempio sostituisci - > ripeti, ingoia - > avvolgi).

Quindi, per me la linea di fondo è che il blocco di gestione delle eccezioni risolve problemi che in realtà non esistono. Il bit di registrazione e notifica delle eccezioni va bene, ma le altre cose non sono solo un esempio perfetto per l'ingegnerizzazione?

È stato utile?

Soluzione

Se si utilizzano le eccezioni per il flusso di controllo, si desidera evitare la gestione delle eccezioni basata su criteri.

Ma nel caso di eccezioni che si desidera considerare non recuperabili (un'attività in background non è riuscita, il socket è stato disconnesso, il file è stato eliminato, ecc.), è possibile che si desideri avere una gestione delle eccezioni configurabile e basata su criteri .

Ad esempio, se si sta sviluppando un'API, è possibile che tutte le funzioni dell'API generino solo le eccezioni standard ( ArgumentException , ecc.), nonché la propria libreria specifica eccezione nel caso di un'eccezione interna non standard (ad esempio un MyLibraryException ). In questo caso, tutto ciò che conta è che qualcosa non ha funzionato correttamente. Non stai separando l'eccezione e capendo cosa è andato storto. Stai semplicemente riconoscendo il fatto che alcune cose sono andate male e che dovresti fare alcune cose ora.

Quella qualcosa dovrebbe essere configurabile, perché non importa davvero cosa fai. Visualizza una finestra di messaggio per l'utente? Modale o non modale? Registra l'eccezione? Come si desidera registrare l'eccezione? Chiamare un servizio Web di registrazione? Aggiungi a un file di registro? Scrivi nel registro eventi di Windows? Inserire una voce nel database? Inserire una voce in due database? Non importa davvero per il resto dell'applicazione. La scelta di come gestire un'eccezione è completamente ortogonale al resto dell'applicazione.

(A parte questo, non è così che approccerei la gestione delle eccezioni configurabile basata su criteri. Tenderei di più verso uno stile AOP, come la registrazione di un intercettore del logger di eccezioni nel contenitore.)

Altri suggerimenti

Incontro questo problema quando sto sviluppando funzioni che non hanno uno stato recuperabile. Ritengo che questa gestione delle eccezioni basata sulle politiche sia effettivamente utile e garantisca che tutti gli altri sviluppatori che fanno parte di questo progetto aderiscano effettivamente a uno standard per le eccezioni non recuperabili.

Sono d'accordo con i poster sopra, potresti voler evitare le eccezioni basate sulla politica se le stai usando per il flusso di controllo.

Devo concordare con l'affermazione che "il blocco di gestione delle eccezioni risolve problemi che in realtà non esistono nella pratica." Ho usato il blocco dalla sua uscita e raramente mi sembra di guadagnare molto usando. Beh, forse un po 'di mal di testa. :)

Prima di iniziare, devo ammettere che mi piace Shielding alle eccezioni al WCF Limiti del servizio funzionalità. Tuttavia, che è stato aggiunto abbastanza di recente, non prevede alcuna codifica, ma solo attributi e configurazione, e non è come il blocco viene solitamente venduto. Ecco come Microsoft lo mostra a http://msdn.microsoft.com/en -us / library / cc309250.aspx

 alt text

Ai miei occhi quanto sopra è il controllo del flusso.

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

Quando si combina l'aspetto del controllo di flusso con il codice sopra, non si sta sicuramente facendo apparire un codice sbagliato sbagliato. (Non importa che il costrutto if (rethrow) non offra molta astrazione.) Ciò può rendere la manutenzione più difficile per gli sviluppatori che non hanno familiarità con le definizioni dei criteri. Se postHandlingAction nel file di configurazione viene modificato (probabilmente accadrà ad un certo punto) probabilmente troverai che l'applicazione si comporta in modi inaspettati che non sono mai stati testati.

Forse non lo troverei discutibile se il blocco non gestisse il controllo del flusso ma ti permettesse semplicemente di gestire insieme i gestori.

Ma forse no. In realtà non ricordo di aver mai chiesto di:

  • aggiungi una nuova funzionalità quando gestisci un'eccezione (ad esempio oltre a accedere al registro eventi anche inviare un'email. In realtà, il blocco di registrazione può farlo da solo se stavi già registrando tu stesso l'eccezione. :) )
  • modifica il comportamento di gestione delle eccezioni (ingoia, rilancia o lancia nuovo) in un'intera "politica".

Non sto dicendo che non accada (sono sicuro che qualcuno ha una storia!); Sento solo che il blocco delle applicazioni per la gestione delle eccezioni rende i programmi più difficili da comprendere e mantenere e questo di solito supera le funzionalità fornite dal blocco.

Non penso affatto che sia finita l'ingegneria. infatti. il fatto che le eccezioni possano passare attraverso un gestore centrale è stata una buona cosa nella mia linea di lavoro. ho avuto sviluppatori che avrebbero mangiato tutte le eccezioni - gestiti o meno in modo che non arrivassero in cima e mettessero qualcosa di allarmante davanti all'utente finale o rovinassero seriamente un servizio / demone quando non rilevati.

ora con la politica possiamo iniziare la registrazione in qualsiasi momento senza dover riavviare o cospargere inutilmente la logica di registrazione in tutta l'app. ora possiamo guardare eccezioni e simili senza portare offline l'app.

programmazione intelligente se me lo chiedi ...

Molto semplicemente: se si desidera una diversa gestione delle eccezioni nel codice di rilascio rispetto al codice di debug, sarebbe utile.

A mio avviso, un valore reale dell'utilizzo del blocco Gestione eccezioni inizia con una riga di codice nel blocco catch:

bool rethrow = ExceptionPolicy.HandleException (ex, " Politica di accesso ai dati ");

Una riga di codice: quanto puoi ottenere semplice? Dietro una riga di codice, la politica, così come è configurata, consente di eseguire facilmente assegnazioni / aggiornamenti a una politica, il tutto senza dover ricompilare il codice sorgente.

Come accennato, la politica delle eccezioni può effettivamente eseguire molte azioni, qualunque cosa sia definita nella politica. Nascondere la complessità dietro una riga di codice, come mostrato all'interno del blocco catch, è dove vedo il valore reale.

Direi complesso, ma non troppo ingegnerizzato. Quindi i miei pensieri sono che durante la manutenzione si vedranno grandi dividendi quando è necessario cambiare il modo in cui si gestiscono / registrano le eccezioni avendo la flessibilità di cambiare facilmente la configurazione e avere ancora la stessa riga di codice sorgente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top