37

system.net.mail.smtpclient has two methods for which I am very confused.

1 . SendAsync(MailMessage, Object)

Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes. -MSDN

2 . SendMailAsync(MailMessage)

Sends the specified message to an SMTP server for delivery as an asynchronous operation. -MSDN

Notice that the names of two methods are different so it is not an overload. What exactly is the difference here?

I am looking for very clear answer as the description given by MSDN for both methods is very ambiguous (at least for me it is.)

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Bilal Fazlani
  • 6,727
  • 9
  • 44
  • 90

4 Answers4

31

The difference is one SendMailAsync uses the new async/await technology and the other uses the old callback technology. And more importantly, the Object that's passed is simply passed into the event handler as the userState when the method completes.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
  • 7
    Better said: SendMailAsync returns a task. Whether you use await or not is your call. – usr Sep 04 '13 at 13:34
  • 1
    @usr, well said on that. You certainly don't ever have to `await`. – Mike Perrenoud Sep 04 '13 at 13:36
  • I want to know what is the benefit of one over the other ? I am assuming the SendMailAsync is better – Bilal Fazlani Sep 04 '13 at 16:52
  • 1
    @bilalfazlani, there is no benefit of one over the other. They are tools that are available for you to use. If one works with your application better than the other because you use the `async/await` methodology then use the `SendMailAsync` method. If you don't, just hook up the callback on the object and call the `SendAsync` method. Both are completely valid. – Mike Perrenoud Sep 04 '13 at 16:54
  • @neoistheone one last question. In both methods, will the thread used to do the job asynchronously, consumed from thread pool ? – Bilal Fazlani Sep 04 '13 at 17:07
  • @BilalFazlani, the thread will be started and managed on its own, and will be pulled from the thread pool that's available in the `AppDomain`. You can't manage that thread on your own. – Mike Perrenoud Sep 04 '13 at 17:08
11

Firstly, they both work asynchronously.

However, SendAsync has existed since .NET 2. In order to maintain backwards compatiblity whilst supporting the new Tasks system SendMailAsync was added.

SendMailAsync returns a Task rather than void and allows the SmtpClient to support the new async and await functionality if required.

Lloyd
  • 29,197
  • 4
  • 84
  • 98
2
  //SendAsync
public class MailHelper
{

    public void SendMail(string mailfrom, string mailto, string body, string subject)
    {
        MailMessage MyMail = new MailMessage();
        MyMail.From = new MailAddress(mailfrom);
        MyMail.To.Add(mailto);
        MyMail.Subject = subject;
        MyMail.IsBodyHtml = true;
        MyMail.Body = body;
        MyMail.Priority = MailPriority.Normal;

        SmtpClient smtpMailObj = new SmtpClient();
        /*Setting*/
        object userState = MyMail;
        smtpMailObj.SendCompleted += new SendCompletedEventHandler(SmtpClient_OnCompleted);
        try
        {
            smtpMailObj.SendAsync(MyMail, userState);
        }
        catch (Exception ex) { /* exception handling code here */ }
    }

    public static void SmtpClient_OnCompleted(object sender, AsyncCompletedEventArgs e)
    {
        //Get the Original MailMessage object
        MailMessage mail = (MailMessage)e.UserState;

        //write out the subject
        string subject = mail.Subject;

        if (e.Cancelled)
        {
            Console.WriteLine("Send canceled for mail with subject [{0}].", subject);
        }
        if (e.Error != null)
        {
            Console.WriteLine("Error {1} occurred when sending mail [{0}] ", subject, e.Error.ToString());
        }
        else
        {
            Console.WriteLine("Message [{0}] sent.", subject);
        }
    }

    //

}

//SendMailAsync
public class MailHelper
{
    //
    public async Task<bool> SendMailAsync(string mailfrom, string mailto, string body, string subject)
    {
        MailMessage MyMail = new MailMessage();
        MyMail.From = new MailAddress(mailfrom);
        MyMail.To.Add(mailto);
        MyMail.Subject = subject;
        MyMail.IsBodyHtml = true;
        MyMail.Body = body;
        MyMail.Priority = MailPriority.Normal;

        using (SmtpClient smtpMailObj = new SmtpClient())
        {
            /*Setting*/
            try
            {
                await smtpMailObj.SendMailAsync(MyMail);
                return true;
            }
            catch (Exception ex) { /* exception handling code here */ return false; }
        }
    }
}
vicky
  • 1,546
  • 1
  • 18
  • 35
0

SendMailAsync a simple TAP wrapper for SendAsync More info: Are the SmtpClient.SendMailAsync methods Thread Safe?

Community
  • 1
  • 1
lexar
  • 1