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
Vous devez vous connecter pour publier un commentaire.
Votre poing méthode ne fonctionnera pas correctement en raison de l'UTILISATION de bloc. Après l'utilisation de bloc se termine, le SmtpClient objet de cession. Donc vous ne pouvez pas accéder à votre gestionnaire d'événement.
OriginalL'auteur Mithrandir
conseils:
1-ne pas utiliser "en bloc" pour MailMessage objet, jetez votre objet avant de le mail envoyé
2-disposer MailMessage objets sur SmtpClient.SendCompleted événement:
Set de 3 SendCompletedEventHandler pour smtpClient objet
4-plus de code:
OriginalL'auteur daszarrin
SmtpClient.SendAsync
est la méthode préférée de async d'envoi d'emails depuis qu'il utiliseSmtpClient
méthodes spécialement conçues à cet effet. Il est aussi plus simple à mettre en œuvre et a fait ses preuves des milliers de fois.Votre 5 sec de retard est étrange et suggèrent qu'il y a un problème qui doit répondre. Premier morceau de code est tout couvrant le problème mais ne l'élimine pas.
SmtpClient.SendAsync
seront effectivement envoyer uniquement de manière asynchrone si votre méthode de livraison est pasSpecifiedPickupDirectory
ouPickupDirectoryFromIis
. Dans ces cas, il va écrire le fichier de message dans le dossier de collecte avant de retourner. Vérifiez votre fichier de configuration du<smtp>
section. Ma conjecture est que vous utilisez une de ces méthodes et le problème est avec le dossier de collecte. Supprimer les vieux fichiers que vous pourriez avoir là-bas et vérifier si le problème n'est pas de votre logiciel antivirus qui a probablement des recherches de chaque nouveau fichier pour les virus. Vérifiez si il y a de chiffrement ou de compression attributs définis. Peut être autre chose aussi. La meilleure façon de tester si le dossier est la source des problèmes est manuellement à l'adaptation d'un fichier de mail.OriginalL'auteur Maciej D.