Question

edit: cela semble être un point de coller, donc je vais juste l'obtenir de la façon suivante:

Je ne suis pas en utilisant ce pour la synchronisation. Il suffit de tuer des tâches longues à exécuter quand ils ne sont nécessaires / souhaitable.
Hypothétiquement : supposons ces fils simplement écrire à la console (disons: "Thread 1"), le sommeil une longueur aléatoire, puis la sortie. Si elles sont avortés, je veux qu'ils me informer avec une autre écriture de la console (par exemple: « Thread 1 avorté »). Et je veux être en mesure de sauter droit au code abort si je tente d'avorter avant son exécution, sans aucune chance de fonctionner de ses fonctions normales. Si elle est abandonnée pendant le fonctionnement normal, il EPUISES cours à la fois.


J'ai un morceau de fils que je veux courir pour, sur un site ASP .NET 2.0 en cours d'exécution avec Visual Studio 2008 (aucune idée de combien tout ce qui importe, mais il est), et ils peuvent avoir avorté nettoyer Code -up qui devrait être exécuté indépendamment de la distance par leur tâche qu'ils sont. Je fais donc un fil comme ceci:

Thread t = new Thread(delegate() {
   try { 
      /* do things */ 
      System.Diagnostics.Debug.WriteLine("try");
   }
   catch (ThreadAbortException) {
      /* cleanup */ 
      System.Diagnostics.Debug.WriteLine("catch");
   }
});

Maintenant, si je veux abandonner l'ensemble de manière fils partiel à travers, le nettoyage peut être encore plus tard souhaitable sur toute la ligne. En regardant à travers MSDN implique que vous pouvez .Abort () un fil qui n'a pas commencé, puis .Start () il, à quel point il recevra l'exception et fonctionner normalement. Ou vous pouvez Rejoindre à () le fil avorté d'attendre qu'elle se termine l'abandon. On peut supposer que vous pouvez les combiner.

  

http://msdn.microsoft.com /en-us/library/ty8d3wta(v=VS.80).aspx
  Attendre jusqu'à ce qu'un thread a avorté, vous pouvez appeler la méthode d'inscription sur le fil après avoir appelé la méthode Abort, mais il n'y a aucune garantie l'attente se terminera.
  Si Abort est appelé sur un thread qui n'a pas été démarré, le thread abandonnera lorsque Start est appelé. Si Abandonner est appelée sur un thread bloqué ou dort, le fil est interrompu puis avortée.

Maintenant, quand je débogage et pas dans ce code:

t.Abort(); // ThreadState == Unstarted | AbortRequested
t.Start(); // throws ThreadStartException: "Thread failed to start."
// so I comment it out, and
t.Join(); // throws ThreadStateException: "Thread has not been started."

À aucun moment, je ne vois aucune sortie, ni ne les points d'arrêt soit sur le bloc ou essayer des captures s'atteint.
Bizarrement, ThreadStartException ne figure pas en tant que possible de lancer .Start (), d'ici: http://msdn.microsoft.com/en-us/library/a9fyxz7d (v = VS.80) .aspx (ou toute autre version)

Je comprends cela pourrait être évité en ayant un paramètre de démarrage, qui indique si le thread doit sauter sur le code de nettoyage, et qui précède l'appel Abandonner (ce qui est probablement ce que je vais faire). Et je peut .Start () le fil, puis .Abort (le). Mais comme une quantité indéterminée de temps peut passer entre .Start et .Abort, je considère non fiable, et la documentation semble dire que ma méthode originale devrait fonctionner.

Am quelque chose que je manque? La mauvaise documentation?

edit: OW. Et vous ne pouvez pas appeler .Start (param) sur un thread non-paramétrées (Démarrer). Est-il un moyen de savoir si un thread est paramétrés ou non, en dehors de tâtonnement? Je vois un m_Delegate privé, mais public rien ...

Était-ce utile?

La solution

Lorsque vous utilisez ...

t.Abort();
t.Start();

... la innerException du ThreadStartExcpetion contiendra les ThreadAbortExeption comme les États msdn: ( si Abort est appelé sur un thread qui n'a pas été démarré, le thread abandonnera lorsque Start est appelé )

Si vous exécutez ...

t.Start();
t.Abort();

... le ThreadAbortException ne peut jamais occure parce que le fil avait pas le temps de commencer avant qu'elle ne soit annulée.

Si vous testez quelque chose comme ...

t.Start();
Thread.Sleep(100);
t.Abort();

... le code "nettoyage" doit toujours être exécuté.

Si vous devez exécuter le code de nettoyage, même si le fil n'a pas commencé à faire quoi que ce soit une solution possible serait de commencer une méthode de nettoyage en même temps que l'appel Abandonner.

En outre, vous devriez essayer d'éviter les discussions et utiliser des techniques avorter différentes (http://msdn.microsoft.com/en-us/library/ms228964.aspx)

Autres conseils

Je me rends compte que la documentation vous impliquait, mais ce n'est pas ce qui se passe. Si vous interrompez un fil, puis commencer, il ne sera jamais exécuter en aucune façon. Le CLR est assez intelligent pour savoir que le fil-Abandonne sont une entreprise précaire, et l'occasion de sauter l'exécution du fil est donc à ne pas manquer tout à fait.

peut-être faire votre code de nettoyage dans un sous-programme. Si les Aborts de fil parent ou connaît l'abandon, il appelle le code de nettoyage explicitement.

Gardez à l'esprit que la notion de .net de « nettoyage » après un fil abandon, est de décharger le appdomain des ensembles qui ont été exécutaient le fil avorté. Il est une autre façon de dire « ne vous attendez pas à nettoyer bien. » Vous devez d'abord chercher toujours une conception qui ne nécessite pas les discussions avortent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top