5

Sono nuovo nello sviluppo di software e anche nuovo nello stackoverflow, quindi non esagerare.Eccezioni non gestite nella libreria di classi C# per scopi di logging

BACKGROUND: Sto sviluppando una libreria di classi C# che elabora i messaggi xml inviati da un'applicazione di terze parti su tcp/ip (utilizzando i socket asincroni). Sto usando com-interop per esporre la libreria di classi a un'applicazione Vb6. Quando la libreria C# elabora l'xml che riceve tramite il socket, solleva vari eventi a cui l'applicazione vb6 consumante si abbona (in questo modo, quando eventualmente riscriviamo l'intera applicazione in .Net, questo sarà già fatto con questo componente).

DOMANDA: Voglio catturare tutte le eccezioni non gestite SOLO PER SCOPI DI REGISTRAZIONE. In un'applicazione winforms è possibile collegare un evento a AppDomain.CurrentDomain.UnhandledException e Application.ThreadException. Non c'è modo di afferrare in modo simile i dati delle eccezioni per registrare le informazioni in una libreria di classi?

punti importanti:

  • Io non sto cercando di recuperare da queste eccezioni, ma semplicemente il login e lasciare che l'eccezione Propaga e mandare in crash l'applicazione, se necessario.

  • Sto facendo del mio meglio per rilevare tutte le eccezioni specifiche localmente ovunque io sappia che potrebbero verificarsi. Quindi il mio scopo è solo registrare le eccezioni veramente inaspettate.

  • So che alcuni diranno che questo sarebbe un cattivo modello di progettazione. Dovrei invece lasciare che il chiamante si occupi di queste eccezioni. Il problema è che l'applicazione vb6 non ha una gestione degli errori così solida come vorrei. In primo luogo, voglio registrare la traccia dello stack in modo che se l'app vb6 si arresta in modo anomalo a causa della mia DLL, posso visualizzare il log per essere avvisato di potenziali aree del mio codice C# che potrebbero dover essere cambiate.

Qualcuno può fornirmi qualche direzione? L'opzione migliore che ho trovato finora sembra mettere un blocco catch generico in ogni metodo pubblico, registrare l'eccezione e poi lanciarlo. Questo sembra proprio l'ideale:

public void SomeMethod() 
{ 
    try 
    { 
     // try something here... 
    } 
    catch (Exception ex) 
    { 
     Log(ex); 
     throw; 
    } 
} 

Questo non solo sembrare una cattiva progettazione, ma in aggiunta non so cosa sarebbe successo se uno dei callback asincroni causa un'eccezione in un thread diverso rispetto al metodo è stato chiamato sopra. Questo blocco generale di prova/cattura catturerebbe ancora un'eccezione del genere?

Grazie per qualsiasi assistenza.

EDIT: Inizialmente contrassegnato la risposta di @Eric J. come corretta, ma dopo aver tentato di implementare la soluzione ho scoperto che non funzionerà bene con i callback asincroni della classe socket che sto usando . Una volta che si utilizza un thread del threadpool per attivare la richiamata asincrona, non riesco a percepire eccezioni che si verificano successivamente nello stack. Dovrò utilizzare un framework AOP o ci sono altri modi per cogliere queste eccezioni?

+0

Il vero problema era che non avevo un blocco catch di primo livello nelle mie funzioni di callback asincrono. Poiché vengono eseguiti su thread separati (thread thread-pool), le loro eccezioni non eseguono il backup di "bolle" altrove. AOP sembra una buona soluzione per questo scenario per evitare così tanti blocchi di cattura di primo livello. È qualcosa che intendo investire un po 'di tempo in un po' più avanti. –

risposta

2

Se si dispone di un numero limitato di punti di ingresso nella libreria, prendere in considerazione solo ciò che si suggerisce: utilizzare una classe wrapper .NET o una libreria wrapper per eseguire l'interoperabilità effettiva e rilevare/registrare l'eccezione in tale classe wrapper. Restituisce un'eccezione o un codice di errore che la libreria VB6 chiamante sa come gestire (indipendentemente dal fatto che rilanciare l'eccezione o meno dipenda da cosa può gestire il codice VB6).

CrazyDart suggerisce IOC, che è un'alternativa interessante e valida, ma aggiunge anche complessità e curva di apprendimento inizialmente. Certamente dare un'occhiata anche al CIO e considerarlo come una possibilità.

+0

Non sembra la soluzione ideale da un punto di vista paradigmatico, ma ancora una volta, dati i miei limiti di tempo, sembra l'opzione migliore per il presente progetto. Grazie per l'input. Solo per un chiarimento, stai suggerendo un ulteriore livello di wrapping, o solo quello che è richiesto per fare il com interop? –

+0

No, solo un singolo livello che interpone COM e gestisce le eccezioni. Se hai un numero elevato di metodi da avvolgere, dovresti scrivere un piccolo generatore di codice che, ad es. prende una lista di metodi per classe in COM e restituisce il codice C# appropriato. L'ho fatto prima quando ho inserito un livello aziendale COM molto grande. Quindi, se è davvero grande, potrebbe valere la pena investire tempo nel CIO. –

+0

Grazie. Contrassegnare come risposta perché questa soluzione funziona meglio per me in questo momento. –

1

Potresti usare Castle Windsor e un intercettore per questo. È una buona ragione per usare il CIO sui progetti.

http://blog.andreloker.de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx

li ho usati per la registrazione di eccezione, proprio come lei ha affermato, e registrazione delle prestazioni ... tra le molte altre cose che si utilizza intercettori per operazioni.

+0

Ho utilizzato il COI per i progetti e personalmente credo che aggiunga il massimo beneficio a progetti di grandi dimensioni con diversi team responsabili di diverse aree (preoccupazioni diverse). So che sta calpestando il territorio della guerra santa, condividendo solo la mia esperienza personale. –

+0

Tutto ha il suo posto ... la domanda è su un soggetto avanzato IMHO e richiede un approccio piuttosto avanzato per risolvere correttamente. Sono d'accordo con alcuni degli altri post che AOP (quasi come gli intercettori) è un approccio valido. Filosoficamente, alcuni scelgono di non piantare mai un albero da frutto. Io pianta molte volte. Più tardi ho grandi raccolti. Molte persone mi chiedono come sono arrivato ad avere tanti alberi da frutto così belli e dico loro che pianta spesso. Alcuni muoiono e molti non lo fanno. Trascurare l'apprendimento perché è difficile è ciò che rende qualcuno adatto al lavoro di servizio e al lavoro piuttosto che all'ingegneria. – CrazyDart

+0

Grazie CrazyDart. Concordo sul fatto che il problema sembra piuttosto avanzato e potrebbe richiedere un approccio avanzato. Sfortunatamente tutto questo è nuovo per me (ho sviluppato solo per circa 6 mos, a tempo pieno solo per gli ultimi 2 mesi). Ho segnato per il futuro sia il framework AOP che il castello Windsor. Dati i miei limiti di tempo per il presente progetto, mi sto appoggiando all'approccio di Eric. Se hai qualche idea o preoccupazione specifica su questo nello scenario sopra, sentiti libero di consigliare. Grazie ancora. –

1

Si potrebbe o guardare con un framework AOP come Spring.NET o Unity, o, in alternativa guardare un prodotto come PostSharp (se non ho mai provato personalmente PostSharp).

+0

Grazie per le informazioni. Etichetterò questi quadri e tornerò da loro in futuro.Per ora, temo che la curva di apprendimento possa essere troppo grande per essere implementata, dati i miei limiti di tempo sul progetto. –

Problemi correlati