Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SmtpClient.SendAsync Calls are Automatically Cancelled

Whenever I call smtpClient.SendAsync(...) from within my ASP.NET MVC application, the asynchronous requests are automatically cancelled, even though SendAsyncCancel() is never called.

Synchronous .Send(...) requests, on the other hand, go through just fine.

My EmailService service wrapper handles sending asynchronous email with SmtpClient from within my ASP.NET MVC 3 application. A service instance is injected into each MVC controller by StructureMap, which wraps a new SmtpClient instance in a using (...) { } statement.

Here is my EmailService.SendAsync wrapper method for SmtpClient:

public void SendAsync(EmailMessage message)
{
    try
    {
        using (var smtpClient = new SmtpClient(_cfg.Host, _cfg.Port)
        {
            EnableSsl = _cfg.EnableSsl,
            Credentials = _credentials
        })
        {
            smtpClient.SendCompleted += new SendCompletedEventHandler(Email_OnCompleted);

            var mailMessage = new MailMessage(message.From, message.To)
                                {
                                    Subject = message.Subject,
                                    Body = message.Body
                                };

            smtpClient.SendAsync(mailMessage, message);

            _logger.Info(string.Format("Sending async email to {0} with subject [{1}]", message.To, message.Subject));
        }
    }
    catch (Exception ex)
    {
        _logger.Error("Async email error: " + ex);
        throw;
    }

}

Here is my Email_OnCompleted delegate:

public void Email_OnCompleted(object sender, AsyncCompletedEventArgs e)
{
    var mail = (EmailMessage)e.UserState;

    if (e.Error != null)
    {
        _logger.Error(string.Format("Error sending email to {0} with subject [{1}]: {2}", mail.To, mail.Subject, e.Error));
    }
    else if (e.Cancelled)
    {
        _logger.Warn(string.Format("Cancelled email to {0} with subject [{1}].", mail.To, mail.Subject));
    }
    else
    {
        _logger.Info(string.Format("Sent email to {0} with subject [{1}].", mail.To, mail.Subject));
    }
}

Why are async emails being cancelled, but synchronous emails go through just fine? Could it be a dispose issue?

like image 690
Petrus Theron Avatar asked Nov 29 '11 19:11

Petrus Theron


1 Answers

It can definitely be a dispose issue. When you dispose the client it cancels any outstanding async operations.

You should dispose the client in Email_OnCompleted.

An SO post on where to dispose: Dispose SmtpClient in SendComplete?

like image 77
Anders Abel Avatar answered Nov 05 '22 21:11

Anders Abel