简体   繁体   中英

Sending emails, Why sometimes work sometimes operation time out?

I have created a background async task that is supposed to send email with info taken from db. The email is simple and goes something like this:

Reminder, there are assignments for you:

  • AssignmentID:
  • Assignment Name:
  • Assignment Summary:

This is an auto generated email

The query sends to db if there is any outstanding assignments and sends the email to the corresponding emails. The emails are like 40 emails, maybe more depending. The entire application checks this daily and runs forever. The problem is when I run the application exactly on the scheduled time, all the emails get sent and works, but when I run the application and leave it to run forever, and when it hits the scheduled time, it only sends one email, maybe a 2 or 3 more and then the operation times out.

This is the SendEmail Function:

private void SendEmail()
    {
        string connectionString = databaseSettings.Value.ConnectionString;

        try
        {
            using OracleConnection connection = new OracleConnection(connectionString);
            connection.Open();

            using OracleCommand cmd = new OracleCommand("SELECT * FROM Assignment");
            cmd.Connection = connection;
            cmd.CommandType = CommandType.Text;
            DataTable dt = new DataTable();
            using OracleDataAdapter dataAdapter = new OracleDataAdapter();
            dataAdapter.SelectCommand = cmd;
            dataAdapter.Fill(dt);

            _sending = false;
            foreach (DataRow row in dt.Rows)
            {
                _sending = true;
                string username = appSettings.Value.emailUser.ToString();
                string password = appSettings.Value.emailPass.ToString();
                string display = appSettings.Value.emailDisplay.ToString();
                string smtp = appSettings.Value.emailSMTP.ToString();
                bool ssl = appSettings.Value.emailSSL;
                int port = appSettings.Value.emailPort;

                string email = row["EMAIL"].ToString();
                string AssignmentID= row["AssignmentID"].ToString();
                string AssignmentName= row["AssignmentName"].ToString();
                string AssignmentSummary= row["AssignmentSummary"].ToString();

                string Subject = "Assignment Reminder";
                string Body = string.Format("Reminder, there are assignments for you: <br><br>" +
                                             "AssignmentID: " + AssignmentID+ "<br> Assignment Name: " + AssignmentName+ "<br> Assignment Summary: " + AssignmentSummary+
                                             "<br><br>" + "This is auto generated email");

                var smtpClient = new SmtpClient(smtp)
                {
                    Port = port,
                    EnableSsl = ssl,
                    UseDefaultCredentials = false,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    Credentials = new NetworkCredential(username, password)
                };

                var mailMessage = new MailMessage
                {
                    From = new MailAddress(username, display),
                    Subject = Subject,
                    Body = Body,
                    IsBodyHtml = true
                };
                string debug = appSettings.Value.emailDebug.ToString();
                string debugEmail = appSettings.Value.emailDebugAddr.ToString();

                if (debug == "true")
                {
                    mailMessage.To.Add(new MailAddress(debugEmail));
                }
                else
                {
                    //foreach (var emails in email)
                    mailMessage.To.Add(new MailAddress(email));
                }
                
                smtpClient.Send(mailMessage);
                smtpClient.Timeout = 1800000;
                Console.WriteLine("Email Sent Successfully");
            }
            _sending = false;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

All of this is working properly, its just that it times out. When debugging, the debugger stops at "smtpClient.Send(mailMessage);". I tried using the timeout as you can see and it is still not working. My question is why is this happening and how can I fix it?

Also one more thing, I have found a suggestion online here: https://social.msdn.microsoft.com/Forums/en-US/ff467d0a-2ba7-4a2d-853a-c95d1d89bcc6/what-is-the-cause-of-smtpmail-the-operation-has-timed-out?forum=aspgettingstarted

that the only way this guy got around is by creating a list of failed emails that will be executed after the email task is done so that it can try to resend the emails. If this is the only work around, could you please help me with the logic as I do not how to do it.

Are you sending them through Office365? If so, make sure you haven't exceeded their limit of 30 per minute.

Microsoft appears to be recommending MailKit instead of their own older library (the MailKit guy works there anyway), so here are some suggestions if it wasn't the limits:

  • Enable logging like so, new SmtpClient(new ProtocolLogger(Console.OpenStandardError())) , then next time you see a timeout paste the log output here.
  • Using a helper package like MailKitSimplified.Sender would make this much simpler (SSL by default if the server allows it):
var smtpSettings = new EmailSenderOptions(smtpHost, smtpPort, username, password, "");
using var smtpSender = SmtpSender.Create(smtpSettings);
await smtpSender.WriteEmail
    .From("admin@localhost")
    .To("user@example.com")
    .Subject("Assignment Reminder")
    .BodyHtml("Assignments: <br><br>")
    .TrySendAsync();

Note: I wrote the library so I'm open to feature requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM