重用SmtpClient是有原因的,它限制了与 SMTP 服务器的连接数。我无法为报告正在构建的每个线程实例化一个新类SmtpClient类,否则 SMTP 服务器将因连接错误过多而停止。这是我在这里找不到答案时想出的解决方案。
我最终使用AutoResetEvent来保持一切同步。这样,我可以在每个线程中继续调用我的SendAsync,但等待它处理电子邮件并使用SendComplete事件将其重置,以便下一个可以继续。
我设置了自动重置事件。
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
当我的类被实例化时,我设置了共享的 SMTP 客户端。
_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;
然后当我调用异步发送时,我等待事件清除,然后发送下一个。
_autoResetEvent.WaitOne();
_smtpServer.SendAsync(mail, mail);
mailWaiting++;
我使用 SMTPClient SendComplete 事件来重置 AutoResetEvent,以便发送下一封电子邮件。
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--;
}