Comment puis-je arrêter system.threading.timer code> dans sa méthode de rappelle. J'ai référencé
msdn code> strong>, mais je n'ai rien trouvé utile. S'il vous plaît aider. P>
6 Réponses :
timer.Change(Timeout.Infinite, Timeout.Infinite);
Et si je veux le redémarrer plus tard?
Vous pouvez simplement appeler Techniquement, seul le premier paramètre ( Pour plus d'informations, voir méthode Timer.change . p> mytimer.change (timeout.infinite, timeout.infinite) code>. p>
duetime code>) doit être spécifié comme
timeout.infinite code>
pour la minuterie à arrêter. p>
Il vaut mieux le disposer parce que cela capture le sens sémantique mieux. Cela pourrait aussi être plus rapide.
Cela dépend de si l'utilisateur arrête de manière permanente la minuterie, ou si elle le fait la pause pendant un temps et éventuellement le redémarrer ultérieurement. Si vous utilisez .Dispose () code> Pour simplement mettre en pause la minuterie, vous rencontrerez des problèmes si vous souhaitez le redémarrer ou simplement changer le duetime ou la période. Dans ces cas, il est plus sûr (et plus facile) d'utiliser
Timer.changer () code>.
Essayez ceci:
Si vous voulez que vous puissiez laisser la minuterie continuer à tirer la méthode de rappel et inclure le code ci-dessous p> Consultez ce lien aussi: P >
Premièrement, la méthode de rappel doit avoir l'instance de minuterie.
L'incantation simple p> fera fermer la minuterie. Il est possible que la minuterie puisse invoquer une méthode de rappel une fois de plus après le changement, je crois, en fonction de l'état. P> p>
Il vaut mieux le disposer parce que cela capture le sens sémantique mieux. Cela pourrait aussi être plus rapide.
Dépend de la question de savoir si la minuterie doit être redémarrée plus tard ou que vous en avez terminé. L'OP a précisé qu'elle voulait "arrêter la minuterie", pas "Détruire la minuterie". L'instance de minuterie et sa vie sont la responsabilité de son créateur.
Yap avec cette solution qui est le problème, le fil ne s'arrête pas immédiatement.
J'ai découvert la solution difficile qui change (timeout.infinite, timeout.infinite) n'est pas assez fiable et passée à System.Timers.Timer avec Auteset = Faux. P>
Le problème avec la minuterie est qu'il pourrait être appelé après disposition de sa classe propriétaire. La mise en œuvre suivante a fonctionné pour moi en utilisant l'objet État de l'initialisateur de la minuterie. Le tas ne supprimera pas cet objet jusqu'à ce qu'il soit consommé. C'était mon seul moyen de nettoyer gracieusement le rappel de la minuterie.
using System; using System.Threading; namespace TimerDispose { /// <summary> /// A timer-containing class that can be disposed safely by allowing the timer /// callback that it must exit/cancel its processes /// </summary> class TimerOwner : IDisposable { const int dueTime = 5 * 100; //halve a second const int timerPeriod = 1 * 1000; //Repeat timer every one second (make it Timeout.Inifinite if no repeating required) private TimerCanceller timerCanceller = new TimerCanceller(); private Timer timer; public TimerOwner() { timerInit(dueTime); } byte[] dummy = new byte[100000]; /// <summary> /// /// </summary> /// <param name="dueTime">Pass dueTime for the first time, then TimerPeriod will be passed automatically</param> private void timerInit(int dueTime) { timer = new Timer(timerCallback, timerCanceller, //this is the trick, it will be kept in the heap until it is consumed by the callback dueTime, Timeout.Infinite ); } private void timerCallback(object state) { try { //First exit if the timer was stoped before calling callback. This info is saved in state var canceller = (TimerCanceller)state; if (canceller.Cancelled) { return; // } //Your logic goes here. Please take care ! the callback might have already been called before stoping the timer //and we might be already here after intending of stoping the timer. In most cases it is fine but try not to consume //an object of this class because it might be already disposed. If you have to do that, hopefully it will be catched by //the ObjectDisposedException below dummy[1] = 50; //just messing up with the object after it might be disposed/nulled //Yes, we need to check again. Read above note if (canceller.Cancelled) { //Dispose any resource that might have been initialized above return; // } if (timerPeriod != Timeout.Infinite) { timerInit(timerPeriod); } } catch (ObjectDisposedException ex) { Console.WriteLine("A disposed object accessed"); } catch (NullReferenceException ex) { Console.WriteLine("A nulled object accessed"); } catch (Exception ex) { } } public void releaseTimer() { timerCanceller.Cancelled = true; timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Dispose(); } public void Dispose() { releaseTimer(); dummy = null; //for testing GC.SuppressFinalize(this); } } class TimerCanceller { public bool Cancelled = false; } /// <summary> /// Testing the implementation /// </summary> class Program { static void Main(string[] args) { var list = new System.Collections.Generic.List<TimerOwner>(); Console.WriteLine("Started initializing"); for (int i = 0; i < 500000; i++) { list.Add(new TimerOwner()); } Console.WriteLine("Started releasing"); foreach (var item in list) { item.Dispose(); } Console.WriteLine("Press any key to exit"); Console.ReadKey(); } } }
Voir aussi Stackoverflow.com/Questtions/6379541/.../ a>
Est-ce que cela répond à votre question? Système d'arrêt de manière fiable.threading.Timer?