Ogni volta che si chiama smtpClient.SendAsync(...)
dall'applicazione ASP.NET MVC, le richieste asincrone vengono automaticamente annullate, anche se SendAsyncCancel()
non viene mai chiamato.SmtpClient.SendAsync Le chiamate vengono annullate automaticamente
Le richieste sincrone.Send(...)
, d'altra parte, vanno bene.
My EmailService
handle di wrapper di servizio che inviano email asincrona con SmtpClient
dall'interno dell'applicazione ASP.NET MVC 3. Un'istanza di servizio viene iniettata in ogni controller MVC da StructureMap, che include una nuova istanza SmtpClient
in un'istruzione using (...) { }
.
Ecco il mio metodo involucro EmailService.SendAsync
per 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;
}
}
Ecco la mia Email_OnCompleted
delegato:
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));
}
}
Perché i messaggi di posta elettronica asincrone stati cancellati, ma le email sincrone passano bene? Potrebbe essere un problema di smaltimento?
Fantastico! Ho estratto l'uso di (...) e l'invio asincrono ora funziona perfettamente. Grazie, Anders! –
È possibile che il controller venga eliminato insieme a _logger prima che l'invio asincrono sia completato, risultando in un'eccezione di riferimento null nell'istanza di ILogger? –
Più precisamente ... "Quando si smaltisce il client, annulla qualsiasi operazione asincrona in sospeso." = Quando si smaltisce SmtpClient, annulla qualsiasi operazione asincrona in sospeso per l'istanza della classe. –