2011-11-29 10 views
8

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?

risposta

12

Può essere sicuramente un problema di smaltimento. Quando si smaltisce il client, annulla qualsiasi operazione asincrona in sospeso.

È necessario disporre il cliente in Email_OnCompleted.

Un SO postare su dove smaltire: Dispose SmtpClient in SendComplete?

+2

Fantastico! Ho estratto l'uso di (...) e l'invio asincrono ora funziona perfettamente. Grazie, Anders! –

+0

È 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? –

+1

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. –

Problemi correlati