2009-03-09 6 views
2

J'ai obtenu TargetInvocationException lors d'un long processus dans un autre thread causé par un contrôle Windows sur le thread UI (barre de progression). Cette exception conduit mon application à planter (va à la méthode principale dans le débogage) et n'a pas pu être attrapée par try catch. J'ai trouvé ce qui fait cette exception, et la corrige (qui essayait d'assigner la propriété "Value" par une valeur qui dépasse le maximum). Mais cela m'a fait me demander comment je pouvais attraper une telle exception (dans le code de production), donc j'ai une option pour récupérer mon application au lieu de terminer l'application.Comment récupérer gracieusement à partir de TargetInvocationException dans multi thread?

Répondre

2

Il y a des chances que vous ne puissiez pas récupérer beaucoup. En termes de fonctionnement, l'état d'un bon nombre de cadres de pile (et d'objets référencés à partir de ces cadres de pile) est probablement invalide à cause de l'erreur. Pour cette raison, au mieux, vous pouvez récupérer à un niveau très élevé et recommencer l'opération.

Si les ressources auxquelles vous accédez peuvent être contenues dans une transaction, je vous suggère de le faire, afin de ne pas avoir à vous soucier des incohérences dans les données persistantes.

En outre, vous pouvez consulter ce fil sur SO:

Best Practice for Exception Handling in a Windows Forms Application?

Outre la Gestion des exceptions bloc d'application de Microsoft:

http://msdn.microsoft.com/en-us/library/cc309505.aspx

+0

@casperOne: "En termes de fonctionnement, l'état d'un bon nombre de cadres de pile (et d'objets référencés à partir de ces cadres de pile) est probablement invalide à cause de l'erreur." cela semble le facteur le plus possible, dans mon cas l'exception avait été lancée plus de 600 fois à plusieurs reprises. –

0

Intercepter l'exception et trouver un mécanisme pour le renvoyer au code principal ou appelant.

2

Vous pouvez gérer les exceptions (en fait, vous recevez juste une notification) sur le thread graphique via l'événement statique Application.UnhandledException. Lorsque vous attachez un gestionnaire à cet événement, il sera appelé pour toutes les exceptions non gérées sur le thread WinForms UI (pompe de message). Le fait que vous ayez ce gestionnaire attaché signifie que le Application ne se fermera pas. Sans cela, WinForms arrête votre application.

0

Vous ne savez pas quelle version de .net vous utilisez si elle est 3.0+, vous pouvez faire quelque chose le long de ces lignes.

private void UpdateValue(int newValue) 
{ 
    Action myAction =() => progressBar.Value = newValue; 

    if (progressBar.InvokeRequired) 
     progressBar.Invoke(myAction); 
    else 
     myAction(); 
} 

Appelez cette méthode avec la nouvelle valeur de la barre de progression, il vérifiera si les besoins d'appels de triage et faire l'appel approprié. Attention, InvokeRequired est relativement cher, alors utilisez-le uniquement si nécessaire. Vous pouvez en faire une méthode d'extension pour utiliser génétiquement ce modèle pour d'autres contrôles si nécessaire.

Espérons que cela aide.

+0

@Dean: l'exception n'est pas provoquée par l'accès au thread d'interface utilisateur de l'autre thread, cette situation est implémente correctement. quand, disons appeler (myAction) dans votre exemple là où l'exception jeté et n'a pas pu être capturé. Essayez-le et voyez ... merci –

Questions connexes