为什么SmtpClient.SendAsync只能调用一次?
-
23-08-2019 - |
题
我试图写的通知服务(完全合法的非垃圾邮件的目的)在.NET中使用SmtpClient。最初,我只是通过每个消息循环和发送它,但是这是缓慢的,我想提高速度。所以,我切换到使用“SendAsync”,但现在得到的第二个呼叫以下错误:
An asynchronous call is already in progress.
我读这意味着MS残废System.Net.Mail以防止邮件群发。这个对吗?如果是这样,有没有更好的办法做到这一点在.NET中,并且仍然可以登录每封电子邮件的结果(这是很重要的我们的客户)。如果不是,为什么SendAsync只能调用一次?
解决方案
其他提示
您也许可以使用以下命令:
ThreadPool.QueueUserWorkItem(state => client.Send(msg));
这应该允许您的消息进行排队,并作为线程变得可用。
显然,这是不试图停止群发邮件程序。
的原因是,该SmtpClient类不是线程安全的。如果你想同时发送多封电子邮件,你有产卵几个工作线程(有几个方法可以做到的是,在.NET框架),并在他们每个人的创造SmtpClient的单独实例。
我想你误会XXXAsync
类的方法。这些异步调用的目的是允许程序继续运行,而不需要的方法来完成处理并首先返回。然后,您可以与结果进行后来被订阅类似物体的XXXReceived
事件。
要多个邮件同时发送,您可以考虑使用更多的Thread
s。
您可以仅在每SMTP客户端的时刻发送一个。如果你想使一个以上的发送调用,创建多个SMTP客户端。
HTH,
科尔比非洲
由于人在这里注意到了大家,你只能发送一次一个电子邮件,但再派一旦第一已发送的方式是处理SmtpClient类的.SendCompleted事件,然后移动到下一个电子邮件并发送。
如果你想同时发送许多电子邮件,然后为其他人所说,使用多个SmtpClient对象。
有一个原因重用 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;
然后,当我调用send异步,我等待事件清除,然后发送下一个。
_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--;
}