Ich bin etwas ratlos darüber, wie SmtpClient jetzt verwaltet wird, da es verfügbar ist, insbesondere wenn ich mit SendAsync telefoniere. Vermutlich sollte ich Dispose nicht aufrufen, bis SendAsync abgeschlossen ist. Aber sollte ich es jemals nennen (zB mit "using"). Das Szenario ist ein WCF-Dienst, der E-Mails regelmäßig versendet, wenn Anrufe getätigt werden. Der Großteil der Berechnung ist schnell, aber das Senden von E-Mails kann ungefähr eine Sekunde dauern, daher wäre Async vorzuziehen.
Sollte ich jedes Mal, wenn ich E-Mails sende, einen neuen SmtpClient erstellen? Soll ich eine für die gesamte WCF erstellen? Hilfe!
Update Falls es einen Unterschied macht, wird jede E-Mail immer an den Benutzer angepasst. Die WCF wird in Azure gehostet und Google Mail wird als Mailer verwendet.
quelle
Antworten:
Hinweis: .NET 4.5 SmtpClient implementiert die
async awaitable
MethodeSendMailAsync
. Verwenden Sie für niedrigere VersionenSendAsync
wie unten beschrieben.Sie sollten
IDisposable
Instanzen immer zum frühestmöglichen Zeitpunkt entsorgen . Bei asynchronen Anrufen erfolgt dies beim Rückruf, nachdem die Nachricht gesendet wurde.Es ist ein bisschen nervig,
SendAsync
dass kein Rückruf akzeptiert wird.quelle
await
verfügbar war. Dies ist ein traditioneller Rückruf mit Ereignishandlern.await
sollte verwendet werden, wenn die neuere verwendet wirdSendMailAsync
.null
als zweiten Parameter anzugebenSendAsync(...)
?Die ursprüngliche Frage wurde für .NET 4 gestellt, aber wenn es ab .NET 4.5 hilft, implementiert SmtpClient eine asynchrone erwartete Methode
SendMailAsync
.Das asynchrone Senden von E-Mails ist daher wie folgt:
Es ist besser, die SendAsync-Methode zu vermeiden.
quelle
MailMessage
sollte auch entsorgt werden.Im Allgemeinen sollten IDisposable-Objekte so schnell wie möglich entsorgt werden. Die Implementierung von IDisposable für ein Objekt soll die Tatsache kommunizieren, dass die betreffende Klasse teure Ressourcen enthält, die deterministisch freigegeben werden sollten. Wenn das Erstellen dieser Ressourcen jedoch teuer ist und Sie viele dieser Objekte erstellen müssen, ist es möglicherweise besser (in Bezug auf die Leistung), eine Instanz im Speicher zu belassen und wiederzuverwenden. Es gibt nur einen Weg zu wissen, ob das einen Unterschied macht: Profilieren Sie es!
Re: Entsorgen und Async: Sie können nicht
using
offensichtlich verwenden. Stattdessen entsorgen Sie das Objekt normalerweise im Ereignis SendCompleted:quelle
Ok, alte Frage, die ich kenne. Aber ich bin selbst darauf gestoßen, als ich etwas Ähnliches implementieren musste. Ich wollte nur etwas Code teilen.
Ich iteriere über mehrere SmtpClients, um mehrere E-Mails asynchron zu senden. Meine Lösung ähnelt TheCodeKing, aber ich entsorge stattdessen das Rückrufobjekt. Ich übergebe MailMessage auch als userToken, um es im SendCompleted-Ereignis abzurufen, damit ich auch dispose aufrufen kann. So was:
quelle
4.3.2 The maximum number of concurrent connections has exceeded a limit, closing trasmission channel
. Versuchen Sie stattdessen, nur eine Instanz vonSmtpClient
Sie können anhand des folgenden Kommentars erkennen, warum es besonders wichtig ist, SmtpClient zu entsorgen:
In meinem Szenario, in dem ich mehrere E-Mails mit Google Mail gesendet habe, ohne den Client zu entsorgen, habe ich Folgendes erhalten:
quelle