C# 在ASP.net中定期发送邮件
我正在尝试在ASP.NET中定期向用户发送确认邮件 为此,我将邮件排成一个队列,每30秒检查一次。此时将发送队列中的所有确认电子邮件,然后将其从队列中清除 有人知道怎么做吗 这是我发送邮件的代码C# 在ASP.net中定期发送邮件,c#,asp.net,C#,Asp.net,我正在尝试在ASP.NET中定期向用户发送确认邮件 为此,我将邮件排成一个队列,每30秒检查一次。此时将发送队列中的所有确认电子邮件,然后将其从队列中清除 有人知道怎么做吗 这是我发送邮件的代码 public static bool SendMail(string AdminMail,string AdminPassword,string subject,string toAddress, string content,DateTime SendTime) {
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;
}
我使用了一个后台线程来完成这项工作。我做了一些研究,我相信这是一个不错的方法。这里有一些危险,这是不可避免的 主要的事情是确保你永远不会从后台线程抛出异常,因为我相信这会导致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);
}
}
}
public class BackgroundSmtpService
{
private ilogu log=LogManager.GetLogger(typeof(BackgroundSmtpService));
专用只读SmtpService SmtpService;
私有静态线程_watchThread;
私有静态列表_emailToSend=new List();
公共背景SmtpService(SmtpService SmtpService)
{
SmtpService=SmtpService;
}
公开作废发送(电子邮件)
{
锁(_emailToSend)
{
_emailToSend.Add(电子邮件);
}
确保运行();
}
私有无效保证运行()
{
如果(_watchThread==null | |!_watchThread.IsAlive)
{
锁(SmtpService)
{
如果(_watchThread==null | |!_watchThread.IsAlive)
{
_watchThread=新线程(ThreadStart);
_watchThread.Start();
}
}
}
}
私有void ThreadStart()
{
尝试
{
while(true)
{
睡眠(1000);
尝试
{
锁(_emailToSend)
{
var emails=\u emailToSend;
_emailToSend=新列表();
emails.aspallel().ForAll(a=>SmtpService.Send(a));
}
}
捕获(例外e)
{
_log.Error(“运行发送电子邮件时出错”,e);
}
}
}
捕获(例外e)
{
_log.Error(“运行发送电子邮件时出错,外部”,e);
}
}
}
> p>您可能需要考虑使用库。它有很好的文档,而且非常容易使用。这方面的最大挑战是,每当应用程序池进行回收时,都需要一个新的请求来启动“计时器”。如果您有一个HTTP监视器应用程序(如Pingdom)来轮询您的服务器,这应该不会是一个问题,但是您也可以使用第三方监视器工具每隔N秒访问站点上的a页面,该页面将发送邮件并发出响应
我自己也会使用Windows服务从数据库中提取队列并以这种方式发送消息。最简单的方法是创建一个VBScript,将HTTP GET请求发送到
您需要在global.asax应用程序的启动方法中启动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
<>你把代码放在一个有睡眠的WIND循环中,每隔30秒延迟一次……/P>你考虑使用Windows服务吗?你是在ASP.NET网页上做这个还是这是一个应用程序?你能在发送电子邮件的地方显示一些代码吗?我甚至不知道什么是窗口服务:)是的,你可以使用windows服务,设置该服务的标识,并授予该用户在电子邮件服务器中的某些权限。我正在使用asp.net网页进行此操作,我编辑了问题以显示一些代码