简体   繁体   English

发送邮件,为什么有时工作有时操作超时?

[英]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.我创建了一个后台异步任务,它应该发送 email 以及从数据库中获取的信息。 The email is simple and goes something like this: email 很简单,就像这样:

Reminder, there are assignments for you:提醒一下,有作业给你:

  • AssignmentID:作业编号:
  • Assignment Name:作业名称:
  • Assignment Summary:作业摘要:

This is an auto generated email这是自动生成的 email

The query sends to db if there is any outstanding assignments and sends the email to the corresponding emails.如果有任何未完成的分配,查询将发送到 db,并将 email 发送到相应的电子邮件。 The emails are like 40 emails, maybe more depending.这些电子邮件就像 40 封电子邮件,可能更多取决于。 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.问题是当我在预定的时间运行应用程序时,所有的电子邮件都被发送并且有效,但是当我运行应用程序并让它永远运行时,当它达到预定的时间时,它只发送一个 email,也许a 2 或 3 以上,然后操作超时。

This is the SendEmail Function:这是 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);".调试时,调试器在“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还有一件事,我在这里找到了一个在线建议: 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.这个家伙绕过的唯一方法是创建一个失败的电子邮件列表,该列表将在 email 任务完成后执行,以便它可以尝试重新发送电子邮件。 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?您是通过 Office365 发送它们吗? If so, make sure you haven't exceeded their limit of 30 per minute.如果是这样,请确保您没有超过每分钟 30 次的限制

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:微软似乎在推荐 MailKit而不是他们自己的旧库(无论如何 MailKit 人在那里工作),所以如果不是限制的话,这里有一些建议:

  • Enable logging like so, new SmtpClient(new ProtocolLogger(Console.OpenStandardError())) , then next time you see a timeout paste the log output here.像这样启用日志记录, new SmtpClient(new ProtocolLogger(Console.OpenStandardError())) ,然后下次您看到超时时将日志 output 粘贴到此处。
  • Using a helper package like MailKitSimplified.Sender would make this much simpler (SSL by default if the server allows it):使用像 MailKitSimplified.Sender 这样的帮助程序package会使这变得更加简单(如果服务器允许,则默认为 SSL):
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.注意:我编写了库,所以我愿意接受功能请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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