c# .net-4.0

C#¿Cómo desechar correctamente un SmtpClient?



.net-4.0 (6)

El análisis de código de VS 2010 reporta lo siguiente:

Advertencia 4 CA2000: Microsoft.Reliability: En el método ''Mailer.SendMessage ()'', el objeto ''cliente'' no se encuentra en todas las rutas de excepción. Llame a System.IDisposable.Dispose en el objeto ''cliente'' antes de que todas las referencias a él estén fuera de alcance.

Mi código es:

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

¿Cómo debo desechar correctamente al cliente?

Actualización: para responder a la pregunta de Jons, aquí está la funcionalidad de eliminación de archivos adjuntos:

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

Última actualización de la lista de la clase completa (es corta)

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; } }


Esta es la mejor solución que pasará el código de prueba de la policía (y se eliminará si el envío falla):

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


La clase SmtpClient en .NET 4.0 ahora implementa IDisposable , mientras que la clase SmtpClient en .NET 2.0 carece de esta interfaz (como señaló Darin). Este es un cambio importante en el marco y debe realizar las acciones apropiadas al migrar a .NET 4.0. Sin embargo, es posible mitigar esto en su código antes de migrar a .NET 4.0. Aquí hay un ejemplo de esto:

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

Este código se compilará y ejecutará correctamente tanto en .NET 2.0 (+3.0 y 3.5) como en .NET 4.0.


Yo haría algo así:

class Attachments : List<Attachment>, 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(); }

Esto permitiría reutilizar el objeto SmtpClient si desea enviar varios correos.


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


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

De esa manera, el cliente se eliminará incluso si se lanza una excepción durante la llamada al método de Send . Rara vez debería necesitar llamar explícitamente a Dispose ; casi siempre debería estar en una declaración de using .

Sin embargo, no está claro cómo están involucrados los archivos adjuntos aquí. ¿Su clase implementa IDisposable sí? Si es así, ese es probablemente el lugar para deshacerse de los archivos adjuntos que son presumiblemente variables miembro. Si necesita asegurarse de que se eliminen aquí, probablemente necesite:

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


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

Interesante: a diferencia de .NET 3.5, msdn.microsoft.com/en-us/library/… implementa IDisposable en .NET 4.0, aprendiendo cosas nuevas todos los días.