Je recherche de bonnes idées pour implémenter une manière générique d'exécuter une seule ligne (ou un délégué anonyme) de code avec un timeout.
TemperamentalClass tc = new TemperamentalClass();
tc.DoSomething(); // normally runs in 30 sec. Want to error at 1 min
Je recherche une solution qui puisse être mise en œuvre avec élégance dans de nombreux endroits où mon code interagit avec du code capricieux (que je ne peux pas changer).
De plus, j'aimerais que le code «expiré» incriminé cesse de s'exécuter davantage si possible.
c#
multithreading
c#-3.0
asynchronous
timeout
chilltemp
la source
la source
Réponses:
La partie vraiment délicate ici était de tuer la tâche de longue durée en passant le thread de l'exécuteur de l'action à un endroit où il pouvait être abandonné. J'ai accompli cela avec l'utilisation d'un délégué encapsulé qui passe le thread à tuer dans une variable locale dans la méthode qui a créé le lambda.
Je soumets cet exemple, pour votre plaisir. La méthode qui vous intéresse vraiment est CallWithTimeout. Cela annulera le long thread en l'abandonnant et en avalant l'exception ThreadAbortException :
Usage:
La méthode statique qui fait le travail:
la source
Nous utilisons beaucoup de code comme celui-ci dans la production :
La mise en œuvre est open-source, fonctionne efficacement même dans des scénarios de calcul parallèle et est disponible dans le cadre des bibliothèques partagées Lokad
Ce code est encore bogué, vous pouvez essayer avec ce petit programme de test:
Il y a une condition de course. Il est clairement possible qu'une ThreadAbortException soit déclenchée après l'
WaitFor<int>.Run()
appel de la méthode . Je n'ai pas trouvé de moyen fiable de résoudre ce problème, mais avec le même test, je ne peux pas reprocher de problème avec la réponse acceptée par TheSoftwareJedi .la source
Eh bien, vous pouvez faire des choses avec des délégués (BeginInvoke, avec un rappel définissant un indicateur - et le code d'origine attend cet indicateur ou ce délai d'expiration) - mais le problème est qu'il est très difficile d'arrêter le code en cours d'exécution. Par exemple, tuer (ou mettre en pause) un thread est dangereux ... donc je ne pense pas qu'il existe un moyen facile de le faire de manière robuste.
Je publierai ceci, mais notez que ce n'est pas idéal - cela n'arrête pas la tâche de longue durée et ne nettoie pas correctement en cas d'échec.
la source
Quelques changements mineurs à la grande réponse de Pop Catalin:
Des surcharges ont été ajoutées pour prendre en charge le travailleur de signalisation pour annuler l'exécution:
la source
Voici comment je procéderais:
la source
Je viens de le supprimer maintenant, il faudra peut-être une amélioration, mais je ferai ce que vous voulez. C'est une application console simple, mais qui démontre les principes nécessaires.
la source
Qu'en est-il de l'utilisation de Thread.Join (int timeout)?
la source