title: Two ways to send email via SmtpClient asynchronously, different results
body: <p>Simple concept here. This is for a site being built using MVC 3 and Entity Framework 4. After a user registers on the site, an email is sent to their email address. I first implemented this using SmtpClient.Send() and it worked fine. Then I got the bright idea to try sending the email asynchronously. I'm experiencing issues with the two async approaches I've tried.</p>
  
  <p>First implementation (from this unanswered post: <a href="https://stackoverflow.com/questions/7558582/how-to-dispose-using-smtpclient-send-and-asynccallback">https://stackoverflow.com/questions/7558582/how-to-dispose-using-smtpclient-send-and-asynccallback</a>):</p>
  
  <pre><code>public bool Emailer(){
      .
      .
      .
      using (var smtpClient = new SmtpClient())
      {
          smtpClient.EnableSsl = true;
          smtpClient.Host = "smtp.gmail.com";
          smtpClient.Port = 587;
          smtpClient.UseDefaultCredentials = false;
          smtpClient.Credentials = new NetworkCredential("myaddress@gmail.com", "mypassword");
  
          var sd = new SendEmailDelegate(smtpClient.Send);
          var cb = new AsyncCallback(SendEmailResponse);
          sd.BeginInvoke(message, cb, sd);
  
          return true;
      }
  }
  
  private delegate void SendEmailDelegate(System.Net.Mail.MailMessage m);
  
  private static void SendEmailResponse(IAsyncResult ar)
  {
      try
      {
          SendEmailDelegate sd = (SendEmailDelegate)(ar.AsyncState);
          sd.EndInvoke(ar); // "cannot access a disposed object" errors here
      }
      catch (Exception e)
      {
          _logger.WarnException("Error on EndInvoke.", e);
      }
  }
  </code></pre>
  
  <p>This worked half the time. The other half I would get a "Cannot access a disposed object" error in the CallBack.</p>
  
  <p>Next implementation (from a member with solid reputation: <a href="https://stackoverflow.com/questions/7276375/what-are-best-practices-for-using-smtpclient-sendasync-and-dispose-under-net-4/7276819#7276819">What are best practices for using SmtpClient, SendAsync and Dispose under .NET 4.0</a>):</p>
  
  <pre><code>var smtpClient = new SmtpClient();
  smtpClient.EnableSsl = true;
  smtpClient.Host = "smtp.gmail.com";
  smtpClient.Port = 587;
  smtpClient.UseDefaultCredentials = false;
  smtpClient.Credentials = new NetworkCredential("myaddress@gmail.com", "mypassword");
  
  smtpClient.SendCompleted += (s, e) =&gt;
      {
          smtpClient.Dispose();
          message.Dispose();
      };
  smtpClient.SendAsync(message, null);
  </code></pre>
  
  <p>With this implementation I dont get any errors, but there's a noticeably longer delay (~5 seconds) in debugging mode when smtpClient.SendAsync() executes, leading me to think that its not being sent asynchronously.</p>
  
  <p>Questions:</p>
  
  <p>1) what's wrong in the first method that's causing the "disposed object" errors? </p>
  
  <p>2) does the second implementation have a problem that's causing the email to not send asynchronously? Is the 5-second delay meaningless?</p>
  
  <p>Might be also important to note that although the site will not need to support sending a large number of emails (only user registration, opt-in newsletters, etc), we do anticipate a large number of users in the future, hence my decision to send emails asynchronously.</p>
  
  <p>Thanks.</p>