Deux façons d'envoyer un email via SmtpClient de manière asynchrone, des résultats différents

Concept Simple ici. C'est pour un site en cours de construction en utilisant MVC 3 et Entity Framework 4. Après qu'un utilisateur s'enregistre sur le site, un email est envoyé à leur adresse de courriel. J'ai d'abord mis en œuvre cette aide SmtpClient.Send() et il a bien fonctionné. Puis j'ai eu la brillante idée d'essayer d'envoyer l'e-mail de manière asynchrone. Je rencontre des problèmes avec les deux async approches que j'ai essayé.

Première mise en œuvre (à partir de ce post sans réponse: https://stackoverflow.com/questions/7558582/how-to-dispose-using-smtpclient-send-and-asynccallback):

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("[email protected]", "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);
    }
}

Ce travaille la moitié du temps. L'autre moitié, je voudrais obtenir un "Impossible d'accéder à un objet supprimé" erreur dans la fonction de Rappel.

De mise en œuvre suivante (à partir d'un membre, avec une solide reputation: Quelles sont les meilleures pratiques pour l'utilisation de SmtpClient, SendAsync et d'en Disposer en vertu de l' .NET 4.0):

var smtpClient = new SmtpClient();
smtpClient.EnableSsl = true;
smtpClient.Host = "smtp.gmail.com";
smtpClient.Port = 587;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("[email protected]", "mypassword");

smtpClient.SendCompleted += (s, e) =>
    {
        smtpClient.Dispose();
        message.Dispose();
    };
smtpClient.SendAsync(message, null);

Avec cette application je n'obtiens aucune erreur, mais il y a nettement plus de temps (environ 5 secondes) en mode débogage lors de l'smtpClient.SendAsync() s'exécute, me conduit à penser que sa ne soit pas envoyé de manière asynchrone.

Questions:

1) quel est le problème dans la première méthode, qui est à l'origine de la "objet supprimé" erreurs?

2) la deuxième mise en œuvre ont un problème à l'origine de l'e-mail afin de ne pas envoyer de manière asynchrone? Est la retard de 5 secondes de sens?

Peut-être aussi important de noter que, bien que le site n'aurez pas besoin de prendre en charge l'envoi d'un grand nombre d'e-mails (uniquement l'enregistrement de l'utilisateur, l'opt-dans des bulletins d'information, etc), nous ne prévoyons un grand nombre d'utilisateurs dans le futur, d'où ma décision d'envoyer des e-mails de manière asynchrone.

Grâce.

OriginalL'auteur John L | 2012-01-07