VS 2010 code analysis reports the following:
Warning 4 CA2000 : Microsoft.Reliability : In method \'Mailer.SendMessage()\', object \'client\' is not disposed along
This is the neater solution that will pass the code police test (and dispose will always be called if Send fails):
public void SendMessage()
{
using (SmtpClient client = new SmtpClient())
{
client.Send(Message);
DisposeAttachments();
}
}
I would do something like that:
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();
}
This would allow reusing the SmtpClient Object if you want to send multiple mails.
using (SmtpClient client = new SmtpClient())
{
client.Send(Message);
DisposeAttachments();
}
Interesting - contrary to .NET 3.5, SmtpClient implements IDisposable in .NET 4.0, learning new things every day.
public void SendMessage()
{
using (SmtpClient client = new SmtpClient())
{
client.Send(Message);
}
DisposeAttachments();
}
That way the client will be disposed even if an exception is thrown during the Send
method call. You should very rarely need to call Dispose
explicitly - it should almost always be in a using
statement.
However, it's not clear how the attachments are involved here. Does your class implement IDisposable
itself? If so, that's probably the place to dispose of the attachments which are presumably member variables. If you need to make absolutely sure they get disposed right here, you probably need:
public void SendMessage()
{
try
{
using (SmtpClient client = new SmtpClient())
{
client.Send(Message);
}
}
finally
{
DisposeAttachments();
}
}
public void SendMessage()
{
try
{
using (SmtpClient client = new SmtpClient())
{
client.Send(Message);
client.dispose()
}
}
finally
{
DisposeAttachments();
}
}
The SmtpClient
class in .NET 4.0 now implements IDisposable
, while the SmtpClient
class in .NET 2.0 lacks this interface (as Darin noted). This is a breaking change in the framework and you should take appropriate actions when migrating to .NET 4.0. However, it is possible to mitigate this in your code before migrating to .NET 4.0. Here is an example of such:
var client = new SmtpClient();
// Do not remove this using. In .NET 4.0 SmtpClient implements IDisposable.
using (client as IDisposable)
{
client.Send(message);
}
This code will compile and run correctly both under .NET 2.0 (+3.0 and 3.5) and under .NET 4.0.