Es gibt einen Grund für die Wiederverwendung der SmtpClient wird die Anzahl der Verbindungen zum SMTP-Server begrenzt. Ich kann eine neue Klasse nicht instanziieren SmtpClient Klasse für jeden Thread, auf dem die Berichte erstellt werden, oder der SMTP-Server wird mit dem Fehler "zu viele Verbindungen" abgewiesen. Dies ist die Lösung, die ich gefunden habe, als ich hier keine Antwort finden konnte.
Am Ende habe ich eine AutoResetEvent um alles auf dem Laufenden zu halten. Auf diese Weise kann ich weiterhin meine SendAsync in jedem Thread, sondern warten, bis er die E-Mail verarbeitet hat, und verwenden die SendComplete um es zurückzusetzen, damit das nächste Ereignis fortgesetzt werden kann.
Ich habe das Auto-Reset-Ereignis eingerichtet.
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
Ich richte den gemeinsamen SMTP-Client ein, wenn meine Klasse instanziiert wird.
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new System.Net.NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
Wenn ich dann das asynchrone Senden aufrufe, warte ich darauf, dass das Ereignis gelöscht wird, und sende dann das nächste Ereignis.
_autoResetEvent.WaitOne();
_smtpServer.SendAsync(mail, mail);
mailWaiting++;
Ich verwende das SMTPClient SendComplete-Ereignis, um das AutoResetEvent zurückzusetzen, damit die nächste E-Mail gesendet wird.
private static void SmtpServer_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MailMessage thisMesage = (MailMessage) e.UserState;
if (e.Error != null)
{
if (e.Error.InnerException != null)
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: "
+ e.Error.Message + e.Error.InnerException.Message);
}
else
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: " + e.Error.Message);
}
}
else
{
writeMessage("Success:" + thisMesage.Subject + " sent.");
}
if (_messagesPerConnection > 20)
{ /*Limit # of messages per connection,
After send then reset the SmtpClient before next thread release*/
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_messagesPerConnection = 0;
}
_autoResetEvent.Set();//Here is the event reset
mailWaiting--;
}