我有一个控制台应用程序,可以向不同的收件人发送定制的电子邮件(带有附件),我想要并发地发送它们。为了实现这一点,我需要创建单独的SmtpClients,因此我使用QueueUserWorkItem在单独的线程中创建并发送电子邮件。
代码片段如下:
我注意到(间歇性地)有时不是所有的电子邮件都到达了具有上述代码的特定邮箱。我本以为使用
似乎有效。我想,出于某种原因,一些电子邮件在
这可能是我等待邮件发送的方式的问题吗?还是这是实际的Send方法存在问题?通过此行后,电子邮件是否一定已从应用程序发送?
任何关于此的想法都很好,我无法确定真正的原因。
更新
如要求所示,这里是SMTP代码:
代码片段如下:
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());
我注意到(间歇性地)有时不是所有的电子邮件都到达了具有上述代码的特定邮箱。我本以为使用
Send
而不是SendAsync
将意味着电子邮件一定已经从应用程序发送出去。然而,在WaitHandle.WaitAll
行之后添加以下代码行:System.Threading.Thread.Sleep(5000);
似乎有效。我想,出于某种原因,一些电子邮件在
Send
方法执行后仍未发送。给予额外的5秒似乎可以给应用程序足够的时间来完成。这可能是我等待邮件发送的方式的问题吗?还是这是实际的Send方法存在问题?通过此行后,电子邮件是否一定已从应用程序发送?
任何关于此的想法都很好,我无法确定真正的原因。
更新
如要求所示,这里是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();
}
SendAsync
并仅处理完成事件,以便您知道是否已发送所有电子邮件? - Brian