У меня есть консольное приложение, которое отправляет настроенные электронные письма (с вложениями) разным получателям, и я хочу отправлять их одновременно. Мне нужно создать отдельные SmtpClients для достижения этой цели, поэтому я использую QueueUserWorkItem для создания электронных писем и отправки их в отдельных потоках.
Фрагмент
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());
Я заметил (периодически), что иногда не все письма приходят в конкретные почтовые ящики с указанным кодом. Я бы подумал, что использование Send
над SendAsync
будет означать, что электронное письмо определенно отправлено из приложения. Тем не менее, добавив следующую строку кода после строки WaitHandle.WaitAll
:
System.Threading.Thread.Sleep(5000);
Кажется, работает. Я думаю, по какой-то причине некоторые электронные письма все еще не были отправлены (даже после запуска метода Send
). Предоставление этих дополнительных 5 секунд, похоже, дает приложению достаточно времени для завершения.
Возможно, это связано с тем, как я жду отправки электронных писем? Или это проблема реального метода отправки? Было ли письмо определенно отправлено из приложения после прохождения этой строки?
Любая мысль о том, что это было бы замечательно, не может показаться, что я могу указать на истинную причину.
Обновление
В соответствии с запросом здесь указан код SMTP:
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();
}