J'utilise Comment puis-je disposer cette minuterie à l'intérieur d'un rappel. ou renforcement?
MISE À JOUR: Permettez-moi d'expliquer la situation. Je veux essayer d'appeler la méthode "Enregistrer", alors qu'elle jette une exception. Si cela fonctionne, j'ai besoin d'arrêter la minuterie. P> p> threading.timer code>, comme:
5 Réponses :
Essayez ceci:
Timer timer = null; timer = new Timer(new TimerCallback(y => { try { Save(Read(DateTime.Now)); // here i want to dispose this timer timer.Dispose(); } catch { } })); timer.Change(10000, 10000);
Wow, ici, j'essaie de faire cette question compliquée. La solution évidente est en effet un éliminer la déclaration code>. J'ai supposé que cela était déjà exclu comme "pas une option" pour une raison quelconque.
Je suppose que c'était trop évident :-)
Ma perte, votre gain. J'essaie souvent de rendre les choses trop compliquées. +1 pour la solution correcte, mais simple,.
Je ne pense pas que ce soit à 100% de fil, la série d'événements suivants (ridiculement improbable) pourrait théoriquement se produire: 1. Minuterie créée. 2.
@Chuu: Bon point. Je pense que tu as raison. J'ai changé ma réponse en conséquence.
@Jakobchristensen Resharper donne l'avertissement suivant "Accès à la fermeture modifiée"? Coffre-fort d'ignorer l'avertissement dans ce cas?
@ user2383728 Resharper se plaint probablement que Minuterie code> est modifié en dehors du délégué après avoir créé une fermeture autour de la minuterie code>. Vous pouvez ignorer l'avertissement dans ce cas.
Vous devez conserver la référence de la minuterie dans une variable -
public class MyClass { private Timer _timer; public void StartTimer() { _timer = new Timer(new TimerCallback(y=>{ try { Save(Read(DateTime.Now)); _timer.Dispose(); } catch { } }),null,100000,10000); } }
Vous devrez stocker une référence à la minuterie quelque part et transmettre que dans l'état de l'état de la minuterie elle-même. Essayez de créer une classe quelque chose comme ceci: puis utilisez-le dans votre méthode, comme: p>
Voici une meilleure façon de le faire. Lorsque vous utilisez le constructeur avec un seul param (Timercallback), l'état transmis au rappel sera la minuterie elle-même. Voici un exemple de la DOCS MSDN: P> < Pré> xxx pré> http: //msdn.microsoft.com/en-us/library/ms149618(v=VS.110).aspx P> p>
Prenez soin de vous si vous utilisez Multhreading ou multitâche! Si tel est le cas, vous êtes ici, vous êtes le code et une substitution d'un extenseur de méthode AnnexeDeter (.NET 4.0):
private static object syncObj = new object(); public static void CancelAfter(this CancellationTokenSource source, int timeoutMilliseconds, Action code = null) { if (timeoutMilliseconds == 0) return; // No timeout if (source == null) { throw new NullReferenceException(); } if (timeoutMilliseconds < -1) { throw new ArgumentOutOfRangeException("timeout"); } Timer timer = new Timer(delegate(object self) { lock (syncObj) { try { if (null != code) code.Invoke(); source.Cancel(); ((IDisposable)self).Dispose(); } catch (ObjectDisposedException) { } } }); timer.Change(timeoutMilliseconds, -1); } }
Avez-vous essayé d'assigner à une variable, puis à accéder à la variable?
Pourquoi ne pouvez-vous pas simplement envelopper le minuteur code> dans un
en utilisant la déclaration code>?
@Cody parce que la minuterie peut être éliminée plus tôt que prévu.