Ich habe eine Konsolenanwendung, die benutzerdefinierte E-Mails (mit Anhängen) an verschiedene Empfänger sendet und ich möchte sie gleichzeitig senden. Ich muss separate SmtpClients erstellen, um dies zu erreichen, also verwende ich QueueUserWorkItem, um die E-Mails zu erstellen und sie in separaten Threads zu senden.Senden von E-Mails in separaten Threads mit QueueUserWorkItem
Snippet
var events = new Dictionary<Guid, AutoResetEvent>();
foreach (...)
{
ThreadPool.QueueUserWorkItem(delegate
{
var id = Guid.NewGuid();
events.Add(id, new AutoResetEvent(false));
var alert = // create custom class which internally creates SmtpClient & Mail Message
alert.Send();
events[id].Set();
});
}
// wait for all emails to signal
WaitHandle.WaitAll(events.Values.ToArray());
ich bemerkt habe (mit Unterbrechungen), dass manchmal nicht alle E-Mails in den spezifischen Postfächer mit dem obigen Code gelangen. Ich hätte gedacht, dass die Verwendung von Send
über SendAsync
bedeutet, dass die E-Mail definitiv von der Anwendung gesendet wurde. Allerdings Hinzufügen der folgenden Codezeile nach der WaitHandle.WaitAll
Linie:
System.Threading.Thread.Sleep(5000);
scheint zu funktionieren. Ich denke, aus irgendeinem Grund wurden einige E-Mails immer noch nicht gesendet (auch nachdem die Methode Send
ausgeführt wurde). Wenn man diese zusätzlichen 5 Sekunden gibt, scheint die Anwendung genug Zeit zum Beenden zu geben.
Ist das vielleicht ein Problem mit der Art, wie ich auf die E-Mails warten soll? Oder ist das ein Problem mit der tatsächlichen Send-Methode? Wurde die E-Mail definitiv von der App gesendet, nachdem wir diese Zeile passiert haben?
Irgendeine Gedanken Idee ist auf diesem würde groß sein, kann nicht ganz scheinen, meinen Finger auf die eigentliche Ursache zu legen.
aktualisieren
Wie gewünscht hier ist der SMTP-Code:
SmtpClient client = new SmtpClient("Host");
FieldInfo transport = client.GetType().GetField("transport", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo authModules = transport.GetValue(client).GetType()
.GetField("authenticationModules", BindingFlags.NonPublic | BindingFlags.Instance);
Array modulesArray = authModules.GetValue(transport.GetValue(client)) as Array;
modulesArray.SetValue(modulesArray.GetValue(2), 0);
modulesArray.SetValue(modulesArray.GetValue(2), 1);
modulesArray.SetValue(modulesArray.GetValue(2), 3);
try
{
// create mail message
...
emailClient.Send(emailAlert);
}
catch (Exception ex)
{
// log exception
}
finally
{
emailAlert.Dispose();
}
Können Sie ein kurzes, aber vollständiges Programm erstellen, das das Problem aufweist? –
@Lasse Ich werde versuchen die vorgeschlagenen Lösungen dann zu posten, wenn noch nichts. – James
Können Sie Ihren SMTP-Code posten? – ChaosPandion