2009-08-20 8 views
9

È legale e sicuro in C# catturare un'eccezione su un thread e quindi rilanciarlo su un altro.Riesci a rilanciare un'eccezione .NET su un thread diverso?

E.g. è legale

Exception localEx = null; 

Thread mythread = new Thread() {() => 
        { 
         try 
         { 
          DoSomeStuff(); 
         } 
         catch(Exception ex) 
         { 
          localEx = ex; 
         } 
        }); 

myThread.Start(); 
... 
myThread.Join(); 

if(localEx != null) 
    throw localEx; // rethrow on the main thread 

Penso che sia legale, ma ho difficoltà a trovare qualsiasi documento che lo provi. Il più vicino che ho trovato è una breve menzione del trasferimento delle eccezioni tra i thread qui: http://msdn.microsoft.com/en-us/library/ms229005.aspx

+0

È possibile passare un oggetto da un thread a un altro? – Partial

+0

@Partial: certo che puoi. –

risposta

11

Sì, è legale. Le eccezioni sono (in generale) oggetti descrittivi senza affinità di thread.

Faresti meglio avvolgendo il filo eccezione in una nuova eccezione:

throw new Exception("Something descriptive here", localEx); 

In questo modo, l'analisi dello stack in localEx saranno conservati (come il InnerException della nuova eccezione).

+1

-1: hai intenzione di aggiungere una citazione? Se è così, allora prevarrò. –

+0

La tua risposta era "sì, è legale". Penso che ne sia richiesto di più. Hai ampliato la tua risposta al punto in cui il downvote non è necessario. –

+0

Grazie per averlo indicato. Lo farò. –

2

Non vedo perché non funzionerebbe, ma è necessario ricordare che non si sta effettivamente rilanciando l'eccezione. Stai lanciando una nuova eccezione, che sembra essere lo stesso oggetto di eccezione. Ad esempio, la traccia dello stack dirà che è stata generata da "throw localEx;" invece di dovunque provenisse l'eccezione originale.

+0

Grazie. Sì, il rethrow era la parola sbagliata. Userò localEx come eccezione interna per evitare il problema dello stack delle chiamate che menzioni. –

3

Quello che stai facendo non è un rethrow. È una nuova proiezione di un'istanza di eccezione che ti è capitato di avere in una variabile. Anche se si stesse usando un solo thread, questa sarebbe una cattiva idea, in quanto fa apparire l'eccezione come proveniente dal sito "throw". Con più thread, non ho idea di come qualcuno avrebbe capito che c'era stato un cambio di thread.

2

E 'legale e non è un rethrow, si tratta di una nuova eccezione essere gettato su un altro thread (con lo stesso oggetto eccezione)

3

Assolutamente. System.AggregateException viene aggiunto a .NET 4 per lo scopo specifico durante le operazioni parallele.

0

Non so perché pensi che non sia legale. Se fosse illegale sicuramente il compilatore catturerebbe o il runtime genererebbe un'eccezione. In effetti io uso questo modello. @John In un'applicazione Windows Form che chiama i servizi Web utilizzando un thread in background, utilizzo in questo modo. L'eccezione viene quindi gestita nel gestore di livello superiore Application.ThreadException, registrata ecc. Non è necessario sapere in quale thread si è verificata l'eccezione.

Problemi correlati