VB.NET 2010, .NET 4VB.NET Abandonner un appel de méthode asynchrone après le délai
Bonjour à tous,
J'ai un objet System.Timers.Timer qui fait un travail sur son événement écoulé:
Private Sub MasterTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MasterTimer.Elapsed
MasterTimer.Enabled = False
'...work...
MasterTimer.Enabled = True
End Sub
Mon problème est que le travail que ça fait est parfois bloqué. Une partie du travail est la communication en série, donc il pourrait être bloqué en attente d'une réponse de quelque chose. J'ai déjà modifié un peu mon code de communication en série pour, espérons-le, résoudre le problème. Cependant, cette minuterie est fondamentalement le battement de coeur d'une application de contrôle de production et il est très mauvais si elle devait s'arrêter pour une raison quelconque. Je pensais qu'il serait peut-être bon de mettre un time-out à sécurité intrinsèque de sorte que, si le "travail" prend trop de temps, le minuteur puisse se réactiver et essayer à nouveau. Je pensais à quelque chose comme ceci:
Déplacer le travail dans un sous-programme et créer un délégué:
Private Delegate Sub WorkDelegate()
Private Sub Work()
'...work...
End Sub
Appelez le travail en invoquant le délégué puis utilisez WaitOne (délai d'attente) sur le IAsyncResult pour spécifier un Mais, ma question est: Est-ce que cela causerait un problème si Work() était réellement coincé quelque part? En cela, il ré-entrerait un sous-programme qui est déjà en cours d'exécution? Existe-t-il un moyen d'abandonner Work() s'il n'a pas terminé après le timeout? En d'autres termes, il suffit de cesser l'exécution de Work() si result.IsCompleted est False après WaitOne?
Je ne comprends pas vraiment très bien ce genre de choses, donc tous les commentaires seraient grandement appréciés. Peut-être y a-t-il une façon totalement différente d'aborder cela que je ne connais pas?
Merci beaucoup d'avance!
Je voudrais ajouter quelque chose:
Bien que je compte faire quelques réécritures selon les suggestions de Hans, je l'avais déjà prévu une journée d'essais pour tenter d'isoler la source de cette erreur. Jusqu'à présent, cela ne s'est produit que lors de l'exécution de l'application compilée. J'ai passé aujourd'hui (et certains hier) à essayer de reproduire le gel en mode débogage afin que je puisse ajouter quelques points d'arrêt et comprendre ce qui se passe. Jusqu'à présent, le programme n'a pas gelé en mode débogage. Je me demande simplement s'il y a quelque chose de différent dans l'environnement de débogage qui pourrait expliquer cela. C'est peut-être juste que je suis "chanceux", mais je l'ai exécuté probablement trois fois la durée moyenne après laquelle le programme a gelé lors de l'exécution de l'exécutable ... Encore une fois, je suis assez ignorant, mais y at-il quelque chose? unique à propos de l'environnement de débogage qui pourrait expliquer cela? Je mettrai à jour à nouveau s'il se bloque.
Merci pour la réponse. Hmmm, c'est un problème. J'ai lu à propos de la minuterie dans l'espace de noms Threading il y a un moment. Je pense que j'ai décidé d'aller avec le System.Timers.Timer parce qu'il semblait plus simple à utiliser et parce que je n'ai jamais plus de quelques threads actifs dans mon application à un moment donné. Mon intervalle de minuterie est 500ms. Compte tenu de cela, pensez-vous que les problèmes avec plusieurs threads Work() se chevaucheraient probablement. Peu importe, votre point est pris. Je vais essayer de réorganiser les choses en utilisant le Threading.Timer. –
Encore une chose cependant ... Y a-t-il un moyen de tout emballer dans une sorte de délai d'attente sûr qui forcerait le temporisateur à arrêter immédiatement son travail, à se «décoller» et à recommencer. –
Je ne suis pas sûr d'avoir compris le point. Il n'y a pas de 'brush off' si la minuterie ne peut tirer qu'une seule fois. Mais mon but était de regarder ce que SerialPort peut faire et de reconsidérer l'idée du sondage. Polling suce, il brûle des cycles et des threads inutiles et son dur à garder l'état. SerialPort.DataReceived évite l'interrogation mais pas l'état. Le blocage des appels lus ne nécessite pas d'état, mais brûle un thread. Je sais, difficile quand quelqu'un vous dit que vous devriez réécrire le code à partir de zéro. –