Why can SmtpClient.SendAsync only be called once?

前端 未结 7 1313
暗喜
暗喜 2021-02-02 11:22

I\'m trying to write a notification service (for completely legit non-spam purposes) in .NET using SmtpClient. Initially I just looped through each message and sent it, however

7条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-02 11:49

    There is a reason to reuse the SmtpClient, it limits the # of connections to the SMTP server. I cannot instantiate a new class SmtpClient class for each thread the reports are building on or the SMTP server will balk with too many connections error. This is the solution I came up with when I couldn't find an answer here.

    I ended up using an AutoResetEvent for keeping everything in sync. That way, I can keep calling my SendAsync in each thread, but wait for it to process the email and use the SendComplete event to reset it so the next one can continue.

    I setup the Auto Reset Event.

            AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
    

    I setup the shared SMTP Client when my class is instantiated.

            _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;
    

    Then when I call the send async, I wait for the event to clear, then send the next one.

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

    I use the SMTPClient SendComplete event to reset the AutoResetEvent so the next email will send.

    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--;
            }
    

提交回复
热议问题