2010-03-17 5 views

Répondre

5

Comme Sean a dit, vous devez faire tout le traitement des exceptions et le nettoyage dans la méthode de fil, vous ne pouvez pas faire dans l'initialisation Thread. Par exemple:

public void Run() 
{ 
    try 
    { 
     Thread thread1 = new Thread(ThreadEntry1); 
     thread1.Start(); 

     Thread thread2 = new Thread(ThreadEntry2); 
     thread2.Start(); 
    } 
    catch (NotImplementedException) 
    { 
     // Neither are caught here 
     Console.WriteLine("Caught you"); 
    } 
} 

private void ThreadEntry1() 
{ 
    throw new NotImplementedException("Oops"); 
} 

private void ThreadEntry2() 
{ 
    throw new NotImplementedException("Oops2"); 
} 

Au lieu de cela, cette approche est plus autonome et, évidemment, fonctionne aussi:

public void Run() 
{ 
    Thread thread1 = new Thread(ThreadEntry1); 
    thread1.Start(); 
} 

private void ThreadEntry1() 
{ 
    try 
    { 
     throw new NotImplementedException("Oops"); 
    } 
    catch (NotImplementedException) 
    { 
     Console.WriteLine("Ha! Caught you"); 
    } 
} 

Si vous voulez savoir si le thread a échoué, alors vous devriez envisager un tableau de WaitHandles et retournez à votre méthode d'appel. Une autre approche et plus simple consiste à augmenter simplement un compteur à chaque fois que le fonctionnement d'un fil se termine:

Interlocked.Increment(ref _mycounter); 
1

A. Vous avez une pile d'appel, et vous pouvez l'attraper à l'intérieur du fil et ajouter l'identifiant de fil dans le journal ... Je suppose que

Si vous enveloppez votre fil d'une bonne façon, vous pouvez ajouter Cleaing code à la section catch, terminant le thread si nécessaire.

+0

D'accord. Je ne vois pas cela comme un problème - vous commencez un fil, il va dans une de vos méthodes ... alors qu'est-ce qui vous empêche de gérer les exceptions là-bas? – TomTom

2

Si vous êtes inquiet à propos de ce genre de chose, alors vous devriez envelopper votre point d'entrée de thread dans un bloc try/catch et faire le nettoyage explicitement. Toute exception sortant du point d'entrée du fil entraînera l'arrêt de votre application.

+0

Vous ne pouvez pas capturer ThreadAbortException dans .Net 3.5 ou version inférieure avec les paramètres par défaut et vous ne pouvez pas intercepter des exceptions qui pourraient représenter un état corrompu dans .Net 4.0, également avec les paramètres par défaut. Vous ne pouvez donc pas attraper toutes les exceptions avec un bloc try catch en utilisant les paramètres par défaut (ce n'est pas recommandé) –

+3

Il ne lance pas ThreadAbortException sauf si vous annulez le thread - vous pouvez également les attraper, mais pas les avaler comme ils sont re-élevés automatiquement –

+0

@Chris S, vous avez raison +1, j'ai utilisé capture avec le sens de la déglutition, ce qui n'est pas politiquement correct. –

1

Vous pouvez intercepter des exceptions dans les threads comme vous le feriez pour toute fonction normale. Si votre fonction « travail » pour un fil est appelé DoWork faire quelque chose comme ceci:

private void DoWork(...args...) 
{ 
try 
{ 
// Do my thread work here 
} 
catch (Exception ex) 
{ 
} 
} 
1

Eric Lippert a une post récente sur le mauvais état des exceptions qui se produisent dans les discussions des travailleurs. Il vaut la peine de lire et de comprendre qu'une exception est "exceptionnelle" et la seule chose dont vous pouvez être sûr après une exception dans un thread de travail est que vous ne pouvez plus être sûr de l'état de votre application.

Questions connexes