在后台线程中发送电子邮件需要注意什么?ASP.NET

7

我有一个在后台运行的线程,它会在等待唤醒时休眠并从数据库中拉取数据。我使用SmtpClient发送谷歌应用程序的电子邮件(代码如下)。

我想知道是否有什么需要注意的地方?我计划一次只发送一封电子邮件(注册或忘记密码电子邮件)。我有些担心可能会发生某些问题,例如无效的电子邮件锁定线程,因为我没有设置超时,或者谷歌应用程序已完成并导致应用程序崩溃。我应该注意什么?我还应该问如何进行测试?

        var client = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential(fromAddr, pass),
            EnableSsl = true
        };
        MailMessage mail = new MailMessage(fromAddr, toAddr, subject, body);
        mail.IsBodyHtml = true;
        client.Send(mail);

2
你为什么不能直接从“触发”唤醒它的地方调用这个逻辑呢?如果您尝试发送密码重置并失败了,作为用户,我可能想知道并看到一个漂亮的错误提示,以便我不会坐在那里刷新我的收件箱等待它。处理用户请求和一次性发送所有内容的轻微延迟可能值得消除信号的复杂性。 - Rosstified
4个回答

3
如果您正在使用IIS,请在服务器上安装SMTP并将所有邮件发送到本地主机。这样,如果电子邮件不能立即发送,SMTP服务器将排队该电子邮件,而不是挂起应用程序。
您需要配置SMTP服务器以使用gmail作为智能主机。如果您需要有关如何配置此内容的更多信息,请告诉我。

这也是我做的方式 - 它更快,更可靠。如果您的任何收件人无效或其SMTP服务器已关闭,则会出现超时和/或异常。这种方式,IIS立即接受所有邮件,然后负责发送消息,包括在发送操作失败时重试发送操作。 - Richard

2

在代码中添加try/catch语句,这样就可以解决问题了。最坏的情况下,它会超时。它不会一直运行,Google也不会永远保持连接(事实上,SMTP在超时方面非常严格...如果你太慢了,它会终止连接)。

    try
    {
        var client = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential(fromAddr, pass),
            EnableSsl = true
        };
        MailMessage mail = new MailMessage(fromAddr, toAddr, subject, body);
        mail.IsBodyHtml = true;
        client.Send(mail);
    }
    catch
    {
        // do something
    }

当涉及到测试时...使用另一个gMail帐户。 另外,您可能需要检查每天发送电子邮件的限制。 不确定gMail的数量是多少,但他们不允许您随意发送任意数量的电子邮件。


-1:你几乎永远不应该使用“catch {}”。它会隐藏所有异常。异常并不会因为你看不到它们而消失。 - John Saunders
2
嗯,他确实说了//做些什么 - Adrian Zanescu
4
-1?我没写catch{}。我在那里留了一个注释,告诉他们要做什么。我怎么知道他们需要做什么呢? - Clarence Klopfstein

1

我假设这是在ASP.Net下完成的,因为它是其中之一的标记。

这个过程有多重要?如果您的环境允许,则这可能是Windows服务的一个很好的选择,而不是ASP.Net运行时的一部分。

您已经提到了从数据库中提取数据并发送电子邮件。这些都不依赖于ASP.Net。此外,服务可能会为您提供更好的线程处理,测试,日志记录和异步选项。

如果您想继续使用ASP.Net运行时,则如果您尚未使用异步页面,您也可以考虑这个选项。这将允许您生成多个邮件线程,并使您的主页线程等待结果。您还可以设置超时值,以便取消和记录卡住的线程。我认为,设置和处理异步超时会解决您大部分的问题。这个解决方案至少会将您的邮件发送从主页请求线程中取出。

测试应该是直截了当的。您可以为测试注册单独的Google帐户。


0
您可以设置SmtpClientTimeout属性,然后处理由Send调用引发的任何异常。这样就不会锁定线程,但您必须根据需要处理异常的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接