c#DONS'中的电子邮件发送服务;服务器超时后无法恢复

c#DONS'中的电子邮件发送服务;服务器超时后无法恢复,c#,email,.net-4.5,smtpclient,C#,Email,.net 4.5,Smtpclient,我已经有这个问题好几个月了,快把我逼疯了。 我有一个用C#(.NET4.5)编写的windows服务,它基本上使用outlook帐户发送电子邮件(我认为这是一个office365服务)。我意识到“凭证顺序”问题,这对我没有影响(许多电子邮件发送正确) 服务正确启动并开始发送电子邮件。有时,当有太多的错误时,我会遇到服务器错误等待,服务会等待几分钟,然后完全自行继续 在这些情况下,我得到一个错误: System.Net.Mail.SmtpException: The operation has

我已经有这个问题好几个月了,快把我逼疯了。 我有一个用C#(.NET4.5)编写的windows服务,它基本上使用outlook帐户发送电子邮件(我认为这是一个office365服务)。我意识到“凭证顺序”问题,这对我没有影响(许多电子邮件发送正确)

服务正确启动并开始发送电子邮件。有时,当有太多的错误时,我会遇到服务器错误等待,服务会等待几分钟,然后完全自行继续

在这些情况下,我得到一个错误:

 System.Net.Mail.SmtpException: The operation has timed out.
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at Cobranzas.WinService.Email.SendEmail(String subject, String body, String mailTo, String attPath)
   at Cobranzas.WinService.CobranzasEmailService.SendEmails(IEnumerable`1 toSend, RepositoryEf emailRepo)
问题:有时,我无法找到模式,每隔几天就会发生一次,它会出现超时错误,并且永远不会恢复(重新启动服务会立即修复它。所有后续发送尝试均失败,并出现相同错误。在这种情况下,我得到了错误a和:

 System.Net.Mail.SmtpException: Failure sending mail. ---> System.Net.WebException: The operation has timed out.
   at System.Net.ConnectionPool.Get(Object owningObject, Int32 result, Boolean& continueLoop, WaitHandle[]& waitHandles)
   at System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
   at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   --- End of inner exception stack trace ---
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at Cobranzas.WinService.Email.SendEmail(String subject, String body, String mailTo, String attPath)
   at Cobranzas.WinService.CobranzasEmailService.SendEmails(IEnumerable`1 toSend, RepositoryEf emailRepo)
我的服务逻辑如下:我有一个计时器,它每5分钟对要发送的大量电子邮件进行一次迭代,每次都执行一次

Thread.Sleep(2000); 
try
{
    emailService.SendEmail(asunto, nuevoCuerpo, mail.Email, mail.AlertMessage.Attach);
}
catch (Exception ex)
{
    if (ex is System.Net.Mail.SmtpException)
    {
        Thread.Sleep(20000); // Lo hacemos esperar 20 segundos
    }
}
SendEmail方法是:

var mailMessage = new MailMessage();

mailMessage.To.Add(mailTo);

mailMessage.Subject = subject;
mailMessage.Body = WebUtility.HtmlDecode(body);
mailMessage.IsBodyHtml = true;
mailMessage.From = new MailAddress(emailFromAddress, emailFromName); 
mailMessage.Headers.Add("Content-type", "text/html; charset=iso-8859-1");

// Attachment
if (attPath != null)
{
    var data = new Attachment(attPath, MediaTypeNames.Application.Octet);
    mailMessage.Attachments.Add(data);
}

var cred =
    new NetworkCredential(emailFromAddress, emailFromPassword); 

using (var mailClient =
    new SmtpClient(emailSmtpClient, emailSmtpPort) 
                     {
                         EnableSsl = true,
                         DeliveryMethod = SmtpDeliveryMethod.Network,
                         UseDefaultCredentials = false,
                         Timeout = 20000,
                         Credentials = cred
                     })
{
    mailClient.Send(mailMessage);
}

foreach (Attachment attachment in mailMessage.Attachments)
{
    attachment.Dispose();
}
使用SmtpClient和附件处理是新的,我们添加了它们以尝试修复此问题。行为没有改变。 8.0万T,Tγ-T,Tγ-T,Tγ-T,Tγ-T,Tα-T,Tγ-T,Tα-T,Tα-T,Tα-T,Tγ-T,Tγ-T,Tγ,Tγ-T,Tα-T,Tα-T,Tα-T,Tα-T,T,Tγ-T,Tα-T,T,Tα-2,T,Tα-T,T,T,T,T,T,S,l,l,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,p,p,p,p,p,p,p,p,p,a,a,a,a,a,a,a,a,f,f,f,f,f,f,f,f,f,T,T,T,T,T,T,T,T,"我,我,S,n,e,w,a,n,d,u,n,T,e,S,T,T,e,d,y,e,T

鉴于重新启动服务可以修复它,我怀疑某些东西没有被适当地关闭/清理,但我已经检查过了,找不到可能是什么。我不久前找到了link,但它看起来很旧

非常感谢您的帮助

[进度]


我已经测试了超时后的20英寸等待,但没有任何结果,它仍然以同样的方式失败。有什么想法吗?我们真的被这个问题难住了。

我有完全相同的问题。我在这里找到了解决方案:

发出两个以上并发WebRequest时System.Net.WebException

基本上,我更改了允许并发连接到单个外部服务器的最大连接数。默认情况下,根据该文档,它是2。尽管它有一个超时(它会等待一个超时,直到一个超时被释放,然后继续),但有时,它还不够,并且会挂起

<configuration>
    <system.net>
        <connectionManagement>
        <add address="*" maxconnection="100" />
        </connectionManagement>
    </system.net>
</configuration>


我还没有找到在第一次超时后如何恢复的方法,但我希望这将是“超时”“在一段时间内排除错误。

增加最大连接数可能会有所帮助,但我不能100%确定它是否会推迟问题,直到达到这些连接数为止。”。我决定改用手机。它有自己的SMTP客户机实现,几乎可以替代,并且可以使用常规的
MailMessage
对象(如果您依赖它的话)。它根本不使用连接池,因此它可能是一个更安全的解决方案。

您没有try-catch块来确保在发生异常时,处理它(即记录它或其他),然后让应用程序正常运行。这就是你的应用程序基本崩溃的原因。代码在初次检查时似乎很好,因此我只能建议您的邮件服务可能存在问题。或者,我会检查这会在什么时候导致问题,并调查情况,例如发送了多少封电子邮件或电子邮件消息中包含哪些内容导致超时。是否有一个计时器,每5秒一次?还是几分钟?另外,重新启动服务需要多长时间?如果需要的时间超过5分钟,我会添加一个
Thread.Sleep()发生超时时。因为您的代码看起来很好,所以可能是服务器端的“问题”。(我知道我会每5秒阻止一个试图通过SSL进行身份验证的客户端…)Ahmed,我确实有try-catch块,但在外部部分,我尝试了emailService.SendEmail方法和日志。这就是我记录这些异常的方式。Steffen,5分钟。重启真的很快,大概10秒?我忘了澄清我确实有几个线程睡眠,在发送电子邮件前的2秒钟(我们的想法是在发送一个连接后等待,但我没有将其放入“尝试并捕获”中,而是将其放在了前面。而一个20000个超时后的连接,还没有测试最后一部分。您是否可以尝试管理一次打开的连接数,并多次使用同一个连接,而不是在每次发送操作中都将其杀死?我怀疑这是有问题的。)使用smtp的连接池(您将使用所有连接池)。此外,请在try finally block mailClient.Send(mailMessage);mailClient.ServicePoint.CloseConnectionGroup(mailClient.ServicePoint.ConnectionName)中使用此行;我与@shinax有同样的问题-使用多个SMTP连接的电子邮件发送应用程序在
System.Net.ConnectionPool.Get
中开始超时,当它遇到这种情况时,它在应用程序重新启动之前不会恢复。颠簸
maxconnection
为我解决了问题。添加后会对应用程序产生任何影响吗这个配置?