title: How to send an email with attachments using SmtpClient.SendAsync?
body: <p>I am using a service component through ASP.NET MVC.
  I would like to send the email in a asynchronous way to let the user do other stuff without having to wait for the sending.</p>
  
  <p>When I send a message without attachments it works fine.
  When I send a message with at least one in-memory attachment it fails.</p>
  
  <p>So, I would like to know if it is possible to use an async method with in-memory attachments.</p>
  
  <p>Here is the sending method</p>
  
  <pre><code>
      public static void Send() {
  
          MailMessage message = new MailMessage("from@foo.com", "too@foo.com");
          using (MemoryStream stream = new MemoryStream(new byte[64000])) {
              Attachment attachment = new Attachment(stream, "my attachment");
              message.Attachments.Add(attachment);
              message.Body = "This is an async test.";
  
              SmtpClient smtp = new SmtpClient("localhost");
              smtp.Credentials = new NetworkCredential("foo", "bar");
              smtp.SendAsync(message, null);
          }
      }
  </code></pre>
  
  <p>Here is my current error</p>
  
  <pre><code>
  System.Net.Mail.SmtpException: Failure sending mail.
   ---> System.NotSupportedException: Stream does not support reading.
     at System.Net.Mime.MimeBasePart.EndSend(IAsyncResult asyncResult)
     at System.Net.Mail.Message.EndSend(IAsyncResult asyncResult)
     at System.Net.Mail.SmtpClient.SendMessageCallback(IAsyncResult result)
     --- End of inner exception stack trace ---
  </code></pre>
  
  <hr>
  
  <p>Solution</p>
  
  <pre><code>    public static void Send()
      {
  
              MailMessage message = new MailMessage("from@foo.com", "to@foo.com");
              MemoryStream stream = new MemoryStream(new byte[64000]);
              Attachment attachment = new Attachment(stream, "my attachment");
              message.Attachments.Add(attachment);
              message.Body = "This is an async test.";
              SmtpClient smtp = new SmtpClient("localhost");
              //smtp.Credentials = new NetworkCredential("login", "password");
  
              smtp.SendCompleted += delegate(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
              {
                      if (e.Error != null)
                      {
                              System.Diagnostics.Trace.TraceError(e.Error.ToString());
  
                      }
                      MailMessage userMessage = e.UserState as MailMessage;
                      if (userMessage != null)
                      {
                              userMessage.Dispose();
                      }
              };
  
              smtp.SendAsync(message, message);
      }
  </code></pre>