C # comment éliminer correctement un SmtpClient?

L’parsing de code de VS 2010 indique les éléments suivants:

Avertissement 4 CA2000: Microsoft.Reliability: Dans la méthode ‘Mailer.SendMessage ()’, l’object ‘client’ n’est pas supprimé le long des chemins d’exception. Appelez System.IDisposable.Dispose sur l’object ‘client’ avant que toutes les références à cet object soient hors de scope.

Mon code est:

public void SendMessage() { SmtpClient client = new SmtpClient(); client.Send(Message); client.Dispose(); DisposeAttachments(); } 

Comment dois-je disposer correctement du client?

Mise à jour: pour répondre à la question de Jons, voici la fonctionnalité de suppression des pièces jointes:

 private void DisposeAttachments() { foreach (Attachment attachment in Message.Attachments) { attachment.Dispose(); } Message.Attachments.Dispose(); Message = null; } 

Dernière mise à jour de la liste complète des classes (son court métrage)

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Mail; public class Mailer { public MailMessage Message { get; set; } public Mailer(MailMessage message) { this.Message = message; } public void SendMessage() { using (SmtpClient client = new SmtpClient()) { client.Send(Message); } DisposeAttachments(); } private void DisposeAttachments() { foreach (Attachment attachment in Message.Attachments) { attachment.Dispose(); } Message.Attachments.Dispose(); Message = null; } } 

 public void SendMessage() { using (SmtpClient client = new SmtpClient()) { client.Send(Message); } DisposeAttachments(); } 

Ainsi, le client sera supprimé même si une exception est levée lors de l’appel de la méthode d’envoi. Il est très rare que vous ayez besoin d’appeler explicitement Dispose – cela devrait presque toujours être dans une instruction using .

Cependant, la manière dont les pièces jointes sont impliquées n’est pas claire. Votre classe implémente-t-elle IDisposable elle-même? Si tel est le cas, c’est probablement le lieu de disposer des pièces jointes, qui sont vraisemblablement des variables membres. Si vous devez absolument vous assurer qu’ils sont disposés ici, il vous faut probablement:

 public void SendMessage() { try { using (SmtpClient client = new SmtpClient()) { client.Send(Message); } } finally { DisposeAttachments(); } } 

La classe SmtpClient dans .NET 4.0 implémente maintenant IDisposable , alors que la classe SmtpClient dans .NET 2.0 n’a pas cette interface (comme Darin l’a noté). Il s’agit d’un changement radical dans la structure et vous devez prendre les mesures appropriées lors de la migration vers .NET 4.0. Toutefois, il est possible d’atténuer cela dans votre code avant de migrer vers .NET 4.0. Voici un exemple de ce type:

 var client = new SmtpClient(); // Do not remove this using. In .NET 4.0 SmtpClient implements IDisposable. using (client as IDisposable) { client.Send(message); } 

Ce code sera compilé et exécuté correctement à la fois sous .NET 2.0 (+3.0 et 3.5) et sous .NET 4.0.

 using (SmtpClient client = new SmtpClient()) { client.Send(Message); DisposeAttachments(); } 

Intéressant – contrairement à .NET 3.5, SmtpClient implémente IDisposable dans .NET 4.0, en apprenant de nouvelles choses tous les jours.

Je ferais quelque chose comme ça:

 class Attachments : List, IDisposable { public void Dispose() { foreach (Attachment a in this) { a.Dispose(); } } } class Mailer : IDisposable { SmtpClient client = new SmtpClient(); Attachments attachments = new Attachments(); public SendMessage() { [... do mail stuff ...] } public void Dispose() { this.client.Dispose(); this.attachments.Dispose(); } } [... somewhere else ...] using (Mailer mailer = new Mailer()) { mailer.SendMail(); } 

Cela permettrait de réutiliser l’object SmtpClient si vous souhaitez envoyer plusieurs courriers.

C’est la solution la plus simple qui passera le test de police de code (et sera toujours appelée si l’envoi échoue):

 public void SendMessage() { using (SmtpClient client = new SmtpClient()) { client.Send(Message); DisposeAttachments(); } } 
 public void SendMessage() { try { using (SmtpClient client = new SmtpClient()) { client.Send(Message); client.dispose() } } finally { DisposeAttachments(); } }