代码之家  ›  专栏  ›  技术社区  ›  Daniel

为什么只能调用SmtpClient.SendAsync一次?

  •  22
  • Daniel  · 技术社区  · 17 年前

    我正在尝试使用SmtpClient在.NET中编写一个通知服务(用于完全合法的非垃圾邮件目的)。起初,我只是循环发送每条消息,但是速度很慢,我想提高速度。因此,我切换到使用“SendAsync”,但在第二次调用中出现以下错误:

    An asynchronous call is already in progress. 
    

    7 回复  |  直到 17 年前
        1
  •  35
  •   Darin Dimitrov    17 年前

    根据 documentation :

    调用SendAsync后,必须等待 在尝试发送之前完成 另一封使用“发送”或“发送”的电子邮件

    因此,要同时发送多封邮件,您需要多个SmtpClient实例。

        2
  •  6
  •   kntcnrg    16 年前

    您可能可以使用以下选项:

    ThreadPool.QueueUserWorkItem(state => client.Send(msg));
    

    这将允许消息在线程可用时排队并发送。

        3
  •  4
  •   Tamas Czinege    17 年前

    原因是SmtpClient类不是线程安全的。如果您想同时发送多封电子邮件,您必须生成几个工作线程(在.NET Framework中有几种方法可以做到这一点),并在每个工作线程中创建单独的SmtpClient实例。

        4
  •  4
  •   Gant    17 年前

    我想你误解了我的意思 XXXAsync XXXReceived 对象的事件。

    要同时发送多个邮件,可以考虑使用更多的邮件。 Thread s

        5
  •  2
  •   zekus    17 年前

    每个SMTP客户端一次只能发送一个。如果要进行多个发送呼叫,请创建多个SMTP客户端。

    嗯,,

    科尔比非洲

        6
  •  2
  •   Lasse V. Karlsen    17 年前

    如果您想同时发送多封电子邮件,那么正如其他人所说,请使用多个SmtpClient对象。

        7
  •  2
  •   Billy Willoughby    8 年前

    有理由重用 ,它限制到SMTP服务器的连接数。我无法实例化一个新类 SmtpClient

    最后我使用了一个 保持一切同步。这样,我就可以继续给我的朋友打电话了 在每个线程中,但等待它处理电子邮件并使用 发送完成 事件将其重置,以便下一个事件可以继续。

    我设置了自动重置事件。

            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 async时,我等待事件清除,然后发送下一个事件。

            _autoResetEvent.WaitOne();
            _smtpServer.SendAsync(mail, mail);
            mailWaiting++;
    

    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--;
            }
    
    推荐文章