10

sto lavorando con i seguenti componenti:BackgroundWorker gestione delle eccezioni

  • una libreria (che genera un'eccezione)
  • un banco di prova per testare la mia console di registrazione
  • i blocchi applicativi di gestione delle eccezioni Enterprise Library
  • i blocchi delle applicazioni aziendali biblioteca di registrazione

sto richiamando il metodo libreria utilizzando un backgroundworker. La libreria genera l'eccezione ma il gestore RunWorkerCompleted non viene mai chiamato.

L'unico modo per rilevare l'eccezione è circondare il codice del gestore DoWork con un blocco try/catch.

Si è frainteso la proprietà RunWorkerCompletedEventArgs.Error? Non è per ottenere le eccezioni che sono state scoperte da BackgroundWorker?

codeSample:

static BackgroundWorker w = new BackgroundWorker(); 

w.DoWork += new DoWorkEventHandler(w_DoWork); 
w.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(w_RunWorkerCompleted); 
w.RunWorkerAsync(); 



static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyClass m = new MyClass(); 
    w.result = m.Compute(); 
} 

static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     HandleException(e.Error); 
    } 

    /* result related code */ 

} 


static void HandleException(Exception e) 
{ 
    ExceptionPolicy.HandleException(e, "MyPolicy"); 
} 

Il campione di cui sopra porta ad una cessazione della mia applicazione di console. L'output vs2010 non scrive assolutamente nulla (solo output predefinito).

Quindi dov'è il problema?

// Modifica: questo snippet funziona per intercettare l'eccezione della libreria.

static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     MyClass m = new MyClass(); 
     w.result = m.Compute(); 
    }catch(Exception e){ } 

} 
+1

Hai qualcosa sul thread principale che impedisce la fine? Qualcosa come un po '(vero)? – dcarneiro

+0

Sei sicuro al 100% che RunWorkerCompleted non venga mai chiamato? Ecco una domanda SO che dimostra che dovrebbe funzionare ... http: //stackoverflow.com/questions/1044460/unhandled-exceptions-in-backgroundworker –

+1

non riesci a eseguire il debug e vedere cosa succede? cosa restituisce HandleException()? – Reniuz

risposta

7

Questo è lo schema corretto per BackgroundWorker.

Ho il sospetto che il problema sia che il tuo metodo Main stia uscendo prima che il BW sia completato.

RunWorkerAsync restituirà immediatamente e se non si sta aspettando in Main, quindi il processo terminerà, forse anche prima che il BW è iniziato, non importa completato.

Prova ad aggiungere uno Console.ReadLine alla fine del tuo metodo Main.


Fuori di interesse:

BW si comporta in modo diverso in una console app e un'applicazione di Windows. Se si utilizza un'app WinForms o WPF, sul thread dell'interfaccia utente verrà creato un SynchronizationContext derivato e BW eseguirà il marshalling RunWorkerCompleted sul thread dell'interfaccia utente ed eseguirà lì. Questo è uno dei principali vantaggi di BW.

In un'app console, viene utilizzato il SynchronizationContext predefinito e questo marshals RunWorkerCompleted su un thread del pool di thread. Ciò significa che è possibile bloccare il thread Main e il gestore completo verrà comunque eseguito.

+0

Grazie mille :) – csteinmueller

+0

Ho preso un'app Console, perché è il modo più veloce per testare una libreria. Mi ci vuole molto più tempo per presentare i miei risultati in un'applicazione WPF. – csteinmueller

+7

@MartinJames Trascorro una parte significativa del mio tempo scrivendo app per console che vengono pianificate ed eseguite sui server. Un'interfaccia utente non sarebbe né utile né fattibile per tali situazioni. È anche un po 'più semplice eseguire semplici test in un'app console; meno spese generali coinvolte solo per fare qualcosa di semplice e vedere i risultati. – Servy