在ASP.net中定期发送邮件

时间:2011-12-12 20:42:08

标签: c# asp.net

我正在尝试在ASP.NET中定期向用户发送确认邮件。

要做到这一点,我用邮件填充队列并每隔30秒检查一次。此时队列中的任何确认电子邮件都会被发送,然后从队列中清除。

有谁知道怎么做?

这是我的发送邮件代码

public static bool SendMail(string AdminMail,string AdminPassword,string subject,string toAddress, string content,DateTime SendTime)
        {
            toAddressListProperty.Enqueue(toAddress);

            if(date==null)
            {
                date = DateTime.Now.Second;
            }
            if (date-SendTime.Second > 120)
            {
                    var message = new MailMessage
                                      {
                                          From = new MailAddress(AdminMail)
                                      };

                    foreach (var toAddressl in toAddressListProperty)
                    {
                        message.To.Add(new MailAddress(toAddressl));
                    }

                    message.Subject = subject;
                    message.Body = content;
                    message.IsBodyHtml = true;
                    var smtp = new SmtpClient
                                   {
                                       Credentials = new System.Net.NetworkCredential(AdminMail, AdminPassword),
                                       Port = 587,
                                       Host = "smtp.gmail.com",
                                       EnableSsl = true
                                   };
                    smtp.Send(message);
                //date = SendTime;
                return true;
            }
            return false;
        }

4 个答案:

答案 0 :(得分:1)

我使用后台线程完成了这个。我做了一些研究,我相信这是一个很好的方法。有一些危险,this blog details

主要的是确保你从不从后台线程中抛出异常,因为我认为这将导致Web进程重新启动。此外,如果线程死亡,我确保它在每次调用时都在运行。

我一直使用这种方法几个月,到目前为止没有问题。

此外,我每隔1秒运行一次,这会缩短因关闭应用而丢失电子邮件的时间。

public class BackgroundSmtpService
{
    private ILog _log = LogManager.GetLogger(typeof(BackgroundSmtpService));
    private readonly SmtpService SmtpService;
    private static Thread _watchThread;
    private static List<Email> _emailToSend = new List<Email>();

    public BackgroundSmtpService(SmtpService smtpService)
    {
        SmtpService = smtpService;
    }

    public void Send(Email email)
    {
        lock (_emailToSend)
        {
            _emailToSend.Add(email);
        }
        EnsureRunning();
    }

    private void EnsureRunning()
    {
        if (_watchThread == null || !_watchThread.IsAlive)
        {
            lock (SmtpService)
            {
                if (_watchThread == null || !_watchThread.IsAlive)
                {
                    _watchThread = new Thread(ThreadStart);
                    _watchThread.Start();
                }
            }
        }
    }

    private void ThreadStart()
    {
        try
        {
            while (true)
            {
                Thread.Sleep(1000);
                try
                {
                    lock (_emailToSend)
                    {
                        var emails = _emailToSend;
                        _emailToSend = new List<Email>();
                        emails.AsParallel().ForAll(a=>SmtpService.Send(a));
                    }
                }
                catch (Exception e)
                {
                    _log.Error("Error during running send emails", e);
                }
            }
        }
        catch (Exception e)
        {
            _log.Error("Error during running send emails, outer", e);
        }
    }
}

答案 1 :(得分:1)

您可能需要考虑使用Quartz.net库。它有很好的文档,而且使用起来相当容易。

答案 2 :(得分:0)

您将面临的最大挑战是,只要您的应用程序池回收它,就会需要一个新的请求来为您的“计时器”提供统计数据。如果您有一个HTTP监视器应用程序(如Pingdom)来轮询您的服务器它不应该是一个问题,但是您可以再次使用第三方监视工具来每隔N秒发送一个您网站上的页面邮件并发出回复。

我自己会使用Windows服务从数据库中提取队列并以这种方式发送消息。

答案 3 :(得分:0)

最简单的方法是创建一个向http://localhost/SendConfirmationEmails.aspx发送HTTP GET请求的VBScript

您将在global.asax Application_Start方法中启动VBScript。

SendConfirmationEmails.aspx将充当简单的Web服务(如果需要,您可以使用ashx或实际的Web服务asmx)。它只能在本地主机上访问,因此远程用户无法发送垃圾邮件。

使用Windows服务可能是最好的练习方法,但简单的VBScript将完成工作。

surl="http://localhost/SendConfirmationEmails.aspx"
set oxmlhttp=createobject("msxml2.xmlhttp")
with oxmlhttp
    .open "GET",surl,false
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    .send srequest
end with

你将上面的代码放在一个带有睡眠的循环中,每30秒延迟一次......