Gestire le eccezioni in un ciclo senza interrompere il ciclo (prova ad elaborare tutti i membri)

4

Scenario:

Ho un ciclo che itera su un Array di oggetti COM e fa un po 'di lavoro usandoli.

La mia paura, lavorando con gli oggetti COM, è che alcune eccezioni si insinuano (probabilmente nell'ambiente di un altro utente) e fanno sì che il loop si rompa a metà tra l'elaborazione di questi oggetti.

Quindi, supponiamo (ipoteticamente) che si verifichi un'eccezione sul file 32 di 173.

Vedo tre opzioni:

  1. Mostra l'eccezione, informa l'utente che c'erano solo 32 file elaborati e quindi dobbiamo eseguire manualmente il lavoro sui restanti 141 file.

  2. Annulla tutto il lavoro svolto sui primi 32 file, informa l'utente di la richiesta non può essere completata e mostra l'eccezione. Questo è meno che ideale perché per il momento siamo a questa procedura, un sacco di il lavoro iniziale è stato fatto (creazione di file, incremento di serie numeri, ecc.) che sarebbero ingombranti e difficili da annullare. Alla fine, finiamo con tutti i 172 file che richiedono il lavoro manuale.

  3. Cattura l'eccezione, memorizzala in un elenco, continua a prova elaborare il resto dei file, quindi dopo aver tentato di elaborare tutti i file, informare l'utente di eventuali eccezioni verificatesi e di tutti i file che non è stato possibile elaborare. Caso migliore, abbiamo solo un file su cui lavorare manualmente e il peggiore caso siamo rimasti con 141 file - come la prima opzione.

Orizzonte degli eventi:

Sono nuovo nella programmazione. In effetti ho appena scritto (sto scrivendo) il mio primo add-in che ho pubblicato su SE :: Code Review.

Ora, sono dell'opinione che l'opzione tre abbia più senso - almeno dare una speranza e vedere cosa succede con il resto di loro, no?

Quindi ecco la mia implementazione (ben semplificata, ma questo è lo schema):

Sub Main()
    Dim Exceptions as New List(of Exception)
    Try
        TryThatFunkyCOMthing (Exceptions)

        If Exceptions.Count>0 Then
            For Each ex As Exception in Exceptions
                MessageBox.Show(ex.ToString)
            Next
        End If

    Catch ex As Exception
        MessageBox.Show(ex.ToString)
    End Try
End Sub

Private Sub TryThatFunkyCOMthing (ByRef ExceptionBuffer as List(of Exception))
    For each COMthingy in COMthings
        Try
           COMthingy.DoSomething
        Catch ex As SpecificException
            COMthingy.WeAreBlewedUp
        Catch ex As Exception
            ExceptionBuffer.Add(ex)
        End Try
    Next
End Sub

Uno dei revisori di CR mi ha dato un feedback dicendo che dovrei NON fare questo. Ha detto che dovrebbe volere che il ciclo si fermi se si verifica un'eccezione.

Si è collegato a questo SO Q & A riguardo alla gestione delle eccezioni generali , che I leggere (alcune volte ora) e penso che questa soluzione rientri nel "fallire con grazia". Come accennato in precedenza, non sto cercando di ingoiare le eccezioni, basta controllare come / quando vengono gestite in modo che il mio programma si comporti in un modo da poter prevedere e dipendere, anche in caso di un'eccezione catastrofica o imprevista.

Cosa vorrei sapere:

  1. Se questa è una cattiva pratica, perché?
  2. Tra le tre opzioni che ho fornito, quale sceglieresti? - O - C'è una quarta opzione misteriosa e molto migliore che mi manca?
posta CBRF23 30.07.2015 - 00:39
fonte

2 risposte

5

Capisco perché vuoi farlo. Il modo in cui lo stai facendo non è quello che farei.

Invece di raccogliere un elenco di oggetti di eccezione, vorrei elaborare quegli oggetti nel momento in cui accadono. Raccogliendo un elenco da elaborare in seguito, si rischia di perderli prima che vengano elaborati. A quel punto, senza l'intenzione di farlo, il tuo programma ha ingoiato le eccezioni. L'utente saprà che non è successo niente di male. Quando scoprono, nel modo più duro, la loro esperienza con il tuo programma sarà scadente.

Qualunque cosa tu voglia fare con le eccezioni, fallo non appena si verificano. Continua il ciclo se lo desideri, ma procedi / registra le eccezioni a prescindere.

    
risposta data 30.07.2015 - 01:06
fonte
4

Potresti anche fornire il meglio di entrambi i mondi e solo lasciare che l'utente decida ciò che preferisce .

Ci sono molti software che forniscono attraverso queste impostazioni queste funzionalità:

  • interrompi l'errore
  • ignora errore
  • un annullamento a livello di applicazione

Le prime due opzioni che si escludono a vicenda dovrebbero essere presentate all'utente utilizzando i pulsanti di opzione.

Per annullare / ripristinare, una ricerca sul Web ha evidenziato quanto segue (non verificato):

L'implementazione di queste 3 opzioni non dovrebbe gonfiare in modo significativo il tuo metodo.

    
risposta data 30.07.2015 - 01:02
fonte

Leggi altre domande sui tag