2009-08-20 9 views
9

Est-il légal et sûr en C# d'attraper une exception sur un thread, puis de le rejeter sur un autre.Pouvez-vous relancer une exception .NET sur un thread différent?

E.g. est-ce légal

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 

Je pense que c'est légal, mais j'ai du mal à trouver un doco qui le prouve. Le plus proche que j'ai trouvé était une brève mention du transfert des exceptions entre les discussions ici: http://msdn.microsoft.com/en-us/library/ms229005.aspx

+0

Pouvez-vous passer un objet d'un thread à un autre? – Partial

+0

@Partial: bien sûr, vous pouvez. –

Répondre

11

Oui, c'est légal. Les exceptions sont (en général) des objets descriptifs sans affinité de thread.

Vous seriez mieux envelopper votre exception de fil dans une nouvelle exception:

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

De cette façon, la trace de la pile dans localEx sera conservé (comme InnerException de la nouvelle exception).

+1

-1: Envisagez-vous d'ajouter une citation? Si oui, je vais upvote alors. –

+0

Votre réponse était "oui, c'est légal". Je pense que plus est nécessaire que cela. Vous avez étendu votre réponse au point où le downvote n'est pas nécessaire. –

+0

Merci d'avoir signalé cela. Je vais le faire. –

2

Je ne vois pas pourquoi cela ne fonctionnerait pas, mais vous devez vous rappeler que vous ne réenregistrez pas l'exception. Vous lancez une nouvelle exception, qui se trouve être le même objet d'exception. Ainsi, par exemple, la trace de la pile indiquera qu'elle a été lancée à partir de "throw localEx;" au lieu de l'origine de l'exception originale.

+0

Merci. Oui, renvoyer était le mauvais mot. Je vais utiliser localEx comme exception interne pour éviter le problème de pile d'appel que vous mentionnez. –

3

Ce que vous faites n'est pas une rethrow. C'est un nouveau lancement d'une instance d'exception que vous avez dans une variable. Même si vous n'utilisiez qu'un seul thread, ce serait une mauvaise idée, car cela donne l'impression que l'exception vient du site "throw". Avec plusieurs threads, je n'ai aucune idée de la façon dont quelqu'un comprendrait qu'il y avait eu un changement de thread.

2

Il est légal et ce n'est pas un rethrow, il est une nouvelle exception étant jeté sur un autre fil (avec le même objet d'exception)

0

Je ne sais pas pourquoi vous pensez que ce n'est pas légal. Si c'était illégal, le compilateur l'attraperait sûrement ou l'exécution lancerait une exception. En fait, j'utilise ce modèle. @John Dans une application Windows Forms qui appelle les services Web à l'aide d'un thread d'arrière-plan, j'utilise cette méthode. L'exception est ensuite gérée dans le gestionnaire de niveau supérieur Application.ThreadException, enregistré, etc. Il est inutile de savoir dans quel thread l'exception s'est produite.

Questions connexes