J'utilise la classe System.Timers.Timer dans l'une des classes de mon application. Je sais que la classe Timer a la méthode Dispose héritée de la classe Component parent qui implémente l'interface IDisposable. Les instances de la classe ci-dessous sont créées plusieurs fois au cours du cycle de vie de mon application; chacun d'eux a une instance de classe Timer qui génère des événements Elapsed en continu pendant le cycle de vie de la classe. Dois-je implémenter une interface IDisposable dans la classe qui utilise la classe Timer pour supprimer l'objet timer? (J'ai vu du code qui ne fait rien du tout). J'ai peur que certaines ressources non gérées ne soient pas libérées si j'utilise la classe ci-dessous comme ceci:
SomeClass someClass = new SomeClass();
someClass.DoSomething();
someClass = null;
La classe:
using System.Timers;
public class SomeClass
{
private Timer m_timer;
public SomeClass()
{
m_timer = new Timer();
m_timer.Interval = 1000;
m_timer.Elapsed += new ElapsedEventHandler(m_timer_Elapsed);
m_timer.AutoReset = false;
m_timer.Start();
}
public void DoSomething()
{
}
private void m_timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
//Do some task
}
catch (Exception ex)
{
//Ignore
}
finally
{
if (m_timer != null)
{
//Restart the timer
m_timer.Enabled = true;
}
}
}
}
D'une manière générale, vous devez toujours disposer des ressources disponibles. Je regarderais certainement dans le cas que vous décrivez ci-dessus. Si vous implémentez IDisposable sur la classe qui implémente le minuteur, vous pouvez ensuite utiliser la classe dans une instruction using, ce qui signifie que les ressources seront explicitement libérées lorsque votre classe sera supprimée.
Je vois que vous avez posé cette question il y a un an, mais permettez-moi d'ajouter ma valeur de 2 cents. Un peu moins à cause de l'inflation :). Récemment, j'ai découvert dans notre application que nous ne disposions pas de minuteries. Nous avions une collection d'objets et chaque objet avait une minuterie. Lorsque nous avons retiré l'article de la collection, nous pensions qu'il aurait dû être récupéré. Pour une raison quelconque, ce n'est pas le cas avec les minuteries. Nous avons dû appeler disposer sur l'objet dans la collection pour se débarrasser de la minuterie avant que les objets ne soient réellement récupérés.
La règle générale que j'utilise est de créer tout ce qui a un objet IDisposable, IDisposable lui-même (et de supprimer les objets enfants uniquement lorsque Dispose est explicitement appelé)
Il y a une bonne discussion sur IDisposable sur le blog de Joe Duffy avec des exemples de code qui ressemblent beaucoup à ceux de ma copie de l'excellent Framework Design Guidelines livre
La minuterie doit être éliminée, sinon elle continuera de se déclencher pendant un certain temps après que vous l'ayez "terminée". Cependant, en raison de problèmes de thread, il peut encore se déclencher peu de temps après l'avoir supprimé!
Je suppose que l'objet timer crée ou utilise un thread de travail dans le but de déclencher les événements timer. L'appel dispose va libérer le thread et les ressources qui lui sont associées. Si tel est le cas, ce serait une bonne idée d'appeler dispose afin que vous n'ayez pas trop de threads inutilisés.
En implémentant idisposable, vous serez en mesure de ranger toutes les ressources internes qui implémentent également idisposable comme votre minuterie.
De plus, vous pourrez modifier votre code d'appel pour utiliser la déclaration d'utilisation.
using (SomeClass someClass = new SomeClass())
{
someClass.DoSomething();
}
Je suis d'accord avec Rowland.
Il existe une règle dans FxCop qui recherche les classes contenant des objets jetables, mais qui n'implémentent pas correctement IDisposable.