香港那边公司的市场部开会时要求我们这边实现一个定时发送邮件的功能即在每天下午点左右定时把今天已通过三审的订单信息发给市场部的经理告诉他哪些订单已经通过了终审平时只知道如何发送邮件但不知如何定时发送邮件于是百度了一下总结起来有以下那么三种
()做一个winform 来定时发邮件然后通过windows计划任务设置为指定时间每次自动运行运行完毕后自动关闭
()用sqlserver 数据库实现发邮件用sqlserver实现发邮件的存储过程然后制定一个作业制定时间运行
()在 Globalasax 文件里编程事件Application_Start利用Time类编程比如服务器秒钟执行一次判断
香港那边的公司的ERP糸统是BS模式由于对方公司服务器环境条件的限制我和我师傅决定用第三种方法在编程之前先介绍一下Globalasax文件里的几个方法
protected void Application_Start(Object sender EventArgs e)
{
//Application_start方法请求 ASPNET 应用程序中第一个资源(如页)时调用在应用程序的生命周期期间仅调用一次
}
protected void Application_End(Object sender EventArgs e)
{
//Application_end方法在卸载应用程序之前对每个应用程序生命周期调用一次
}
下面是具体的做法
代码
protected void Application_Start(Object sender EventArgs e)
{
Timer t = new Timer();//设计时间间隔如果一个小时执行一次就改为 这里一分钟调用一次
tElapsed += new ElapsedEventHandler(t_Elapsed);
tAutoReset = true;
tEnabled = true;
}
private void t_Elapsed(object sender ElapsedEventArgs e)
{
if (GetEmailContentGetMailContent()Length == )
{
return;//如果没有通过三审的订单要发送则返回不发送邮件
}
int sendTime_Hour = ConvertToInt(ConfigurationManagerAppSettings[SendTime]ToString());//假如是下午分发送
int now_Hour = ConvertToInt(DateTimeNowHourToString());
int now_Minute = ConvertToInt(DateTimeNowMinuteToString());
int absolute = ;//差距值单位为分钟
if (((now_Hour == sendTime_Hour ) && (now_Minute >= absolute)) || ((now_Hour == sendTime_Hour) && (now_Minute <= absolute))) //即在如果时间判断是落在分至分之间那么就会调用下面的邮件发送方法
{
string subject = stringFormat(CO Approve Report({}) DateTimeNowToString(yyyyMMdd HH:mm:ss));
string host = ConfigurationManagerAppSettings[MailHost];
string from = ConfigurationManagerAppSettings[MailFrom];
string to = ConfigurationManagerAppSettings[MailTo];
string user = ConfigurationManagerAppSettings[MailUser];
string password = ConfigurationManagerAppSettings[MailPassword];
string content = GetEmailContentGetMailContent();
try
{
OrderMailSend(host user password to from subject content null);//发送邮件的方法改为你自己的邮件发送方法
}
catch (Exception ex)
{
throw new Exception(exMessage);
}
}
}
如果一定要确精到分可以设置相距时间为秒级以及设置定时器的时间间隔为秒级比如一秒调用一次t_Elapsed但必须符合的一件条件是定时器的时间间隔<*absoluteabsolute为差距值见上面黄色背景的定义具体多少以客户的要求为准不满足这个条件的话不能实现在规定的时间段内调用邮件发送的方法
好代码编写完毕测试没问题下班再设置晚上点收到邮件(理论值应是点至点分之间收到)当天发现没收到邮件问题来了!为什么在上班的测试没问题但下班后点没收到邮件?网上查了一下发觉自己还有个问题没考虑到Application对象是有生命周期的当网页没人访问或闲置过久应用程序池会调用Application_End方法回收applicatioin里的对象资源导致定时器无法工作
解决方法在IIS以上版本设置IIS应用程序池的回收时间默认好像是分钟可设置长一些但不要太长否则有可能出现网站假死的现象当晚再测试可以正式发送邮件!起码到现在已经用了两三个月都能正常定时发送邮件IIS没有应用程序池可以在C:\WINDOWS\MicrosoftNET\Framework\v\CONFIG\ nfig里面设置具体设置可以参照/
还有对于Applicatioin_Start方法有很多人都会产生一个误解 Application_Start是第一个人访问网站时加载的只会调用一次以后都不会调用Application_Start是第一个人访问网站时加载的这个没错前提是在它的生命周期内有以下几个原因也会导致应用程序池重新启动 即Application_Start可以再次被调用
)添加修改或删除应用程序的 Bin 文件夹中的程序集
)添加修改或删除 App_GlobalResources 或 App_LocalResources 文件夹中的本地化资源
)添加修改或删除应用程序的 Globalasax 文件
)添加修改或删除 App_Code 目录中的源代码文件
)添加修改或删除配置文件配置
)添加修改或删除 App_WebReferences 目录中的 Web 服务引用
)添加修改或删除应用程序的 nfig 文件
附应用程序生命周期概述
附NET垃圾回收机制
附SqlServer发送邮件解决方法:
在正常情况下Application_Start只调用一次这样就不会实例化无数个定时器而占用服务器的资源 还有个问题是定时器的时间间隔如果精确到秒级的话是否会占用很多的内存吃内存是肯定会的所以要根据具体的情况设置应用程序池的回收时间和加大定时器设定的时间间隔
上面定时发送邮件的解决方法只是我个人的做法可供参考不见得是最好的方法QQ邮箱与邮箱都可以实现发送邮件的功能大家可否讨论下他们是怎样实现的