I have a class which implements the IDisposable interface to dispose a private variable _MailMessage
The same class has a async method that makes use of the private IDisposable variable, namely async public Task<bool> Send
My question is: Will the normal IDisposable implementation dispose the private variable after the async method completes? Here is an example of the class I am talking about:
public class Email : IEmail
{
private readonly IEmailData _EmailData;
private MailMessage _MailMessage = new MailMessage();
public Email(IEmailData emailData)
{
if (emailData == null)
{
throw new ArgumentNullException("emailData");
}
if (String.IsNullOrEmpty(emailData.To))
{
throw new ArgumentNullException("emailData.To");
}
if (String.IsNullOrEmpty(emailData.From))
{
throw new ArgumentNullException("emailData.From");
}
if (String.IsNullOrEmpty(emailData.FromName))
{
throw new ArgumentNullException("emailData.FromName");
}
if (String.IsNullOrEmpty(emailData.Subject))
{
throw new ArgumentNullException("emailData.Subject");
}
if (String.IsNullOrEmpty(emailData.Body))
{
throw new ArgumentNullException("emailData.Body");
}
_EmailData = emailData;
}
async public Task<bool> Send()
{
return await Task.Run<bool>(() =>
{
using (SmtpClient smtp = new SmtpClient())
{
smtp.Send(_MailMessage);
}
return true;
});
}
#region "IDisposable implementation"
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Email()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_MailMessage != null)
_MailMessage.Dispose();
}
}
#endregion
}
I have changed the IDisposable implementation according to one of the answer that suggest not to use a destructor:
#region "IDisposable implementation"
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_MailMessage != null)
_MailMessage.Dispose();
}
}
#endregion
I don't see anywhere you're explicitly disposing _MailMessage
other than in Email.Dispose
.
async
doesn't do anything particularly magical with IDispose
; the only thing you have to keep in mind is that async
methods may return early.
So if you call it like this:
using (var email = new Email(...))
{
await email.Send();
}
Then your calling code will (asynchronously) wait for Send
to complete before disposing email
. But if you call it like this:
Task task;
using (var email = new Email(...))
{
task = email.Send();
}
Then your calling code will dispose email
before Send
completes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With