La minuterie ne sont pas éliminés lorsque le formulaire est
Je suis en train d'essayer de comprendre pourquoi un Windows.Forms.Timer
ne sont pas éliminés lors de la form
qui l'a créé. J'ai cette forme simple:
public partial class Form1 : Form {
private System.Windows.Forms.Timer timer;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(OnTimer);
timer.Enabled = true;
}
private void OnTimer(Object source, EventArgs e) {
Debug.WriteLine("OnTimer entered");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
this.Dispose();
}
}
Quand je le ferme, this.Dispose
est appelé, mais la minuterie de cuisson de l'événement continue à être appelé. Je pensais que le Dispose
était de libérer tous les objets appartenant à l'objet supprimé. Est que faux? Ne Timer
ont un comportement spécifique?
Pour l'instant, j'ai trouvé que la manière de disposer de la minuterie est de faire timer.Tick -= OnTimer;
- je l'appelle ensuite dans le Form1_FormClosed
événement. Est-ce la bonne solution ou dois-je faire autrement?
MODIFIER
Ou est-ce simplement de mieux à faire:
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
timer.Dispose();
this.Dispose();
}
?
IDisposable
méthode Dispose
, pas dans FormClosing
dans
FormClosing
cas vous devriez arrêter la minuterie timer.Enabled = false;
et puis timer.Dispose(); timer = null;
Comment est-il préférable de remplacer
Dispose
plutôt de le faire dans FormClosed
?Quelle est l'utilité de
timer.Enabled = false;
et timer = null;
lorsque vous ne timer.Dispose();
? N'est-ce pas Dispose()
prendre soin de tout?Déposer une minuterie à partir de la boîte à outils vers le formulaire avec le concepteur. Maintenant, il est tout automatique.
OriginalL'auteur Otiel | 2011-10-31
Vous devez vous connecter pour publier un commentaire.
Comme je vous l'ai dit dans mon commentaire précédent, vous devriez essayer:
C'est bien parce que vous empêcher la minuterie de cycle (en FormClosing) ou vous pouvez vérifier dans d'autres parties (non dans cet exemple parce que vous êtes à la fermeture du formulaire, mais à titre d'exemple) que si l'objet (timer) a été supprimé avant de l'utiliser.
Donc, en d'autres pièces, vous pouvez faire
OriginalL'auteur Marco
La seule bonne façon de disposer jetables membres d'une
IDisposable
classe est de le faire à l'intérieur de sonDispose(bool disposing)
méthode (vérifier la MSDN l'article). En d'autres termes, vous pouvez ouvrir le générés automatiquementForm.Designer.cs
fichier et de le mettre à l'intérieur de la bonne méthode.D'autre part, si vous ajoutez le
Timer
par VS Designer (au lieu de l'instanciation de vous-même), il sera ajouté à lacomponents
conteneur:et puis éliminés lors de la
components
membre est disposé:Si vous voulez le faire vous-même, gardez à l'esprit que le concepteur n'a pas instancier
components
si elle ne pense pas que c'est nécessaire. Donc,components
pourrait êtrenull
dans votre cas.La façon la plus simple pour résoudre ce problème: ajouter le minuteur en le faisant glisser à partir de la boîte à outils, puis commencer à l'intérieur de la
Form_Load
gestionnaire.OriginalL'auteur Groo
Je ne devrais pas mettre de la ce.Dispose(); dans la forme de clôture de l'événement juste arrêter la minuterie.
OriginalL'auteur Serghei
Le Gestionnaire d'événements est la persistance de la référence, de la suppression de la référence et de l'Arrêt de la minuterie sur le Fermeture Événement ou dès qu'il ne soit pas nécessaire. Si vous voulez vérifier si la Minuterie est disposé le vérifier dans le Cas
OriginalL'auteur Lloyd
La simple
Minuterie.Dispose()
supprime la minuterie de ressources, y compris stopper le chronomètre de tir dans l'avenir.Cependant, il est possible qu'après
Dispose()
retourne, il y a des rappels qui sont activement de l'exécution ou de s'asseoir dans le pool de threads de travail de la file d'attente d'exécution.La seconde surcharge,
Minuterie.Dispose(WaitHandle)
sera le signal de l'adopté dans l'objet une fois tous les rappels pour la minuterie est terminée. Cela peut être toutWaitHandle
, par exemple unManualResetEvent
.Pour simplifier les choses, vous pouvez passer dans
WaitHandle.InvalidHandle
etTimer.Dispose()
sera de retour que lorsque tous les rappels ont terminé. Cela évite d'avoir à allouer un vrai objet de l'événement et est généralement ce que vous voulez faire.Depuis
WaitHandle
est abstrait, vous devez utiliser un peu de bidouille, qui est de créer votre propre sous-classe.OriginalL'auteur Chris Bednarski