问题说明: 前几天做了一个电子邮件定时发送的程序,在实际使用时,发现超过预定完成时间很久,邮件仍未发送完毕。邮件的发送是由 Asp.Net 的后台线程完成,具体的做法是通过一个全局的 Timer,按照指定的时间间隔逐封发送邮件。因为需要发送的邮件数量较多,并且限定了每小时发送邮件的数量为100封,因而整个发送过程大约需要 20 个小时左右。
解决过程: 在仔细检测程序后,发现程序本身并没有问题。于是增加事件跟踪,从 Windows 的事件查看器中,看到 Asp.Net 应用程序会不定时的关闭,这个时间间隔大约为 1~5 个小时一次。据此怀疑是 IIS 的问题,在网上搜索相关资后得知,IIS 为优化服务器性能,会自动对它认为休眠的应用程序进行资源回收,资源回收将会导致网站应用程序关闭。
可通过下述方式检验该结论:
1、首先在 Global.asax 文件的 Application_Start 事件中添加事件记录,标示应用程序的启动,如下:
System.Diagnostics.EventLog.WriteEntry("Beckman", "应用程序启动。",
System.Diagnostics.EventLogEntryType.Information);
在 Application_End 事件中添加应用程序关闭事件记录:
System.Diagnostics.EventLog.WriteEntry("Beckman", "应用程序关闭。",
System.Diagnostics.EventLogEntryType.Information);
2、打开 IIS,选择 Web 应用程序所在的应用程序集,右击后点击“回收”
3、打开 Windows 系统管理工具中的“事件查看器”,可以看到
4、找到问题所在,解决的办法就比较简单,在发送第一个针对该 Web 应用程序的 Http 请求后,IIS 即会自动启动 Web 应用程序,那么,我们可以在Web 应用程序关闭后,提交一个请求给该 Web 应用程序,从而开启关闭的应用程序。程序如下:
在 Application_End 事件中,当 Web 应用程序关闭 5 秒之后,由程序产生一个针对该 Web 应用程序的 Http,IIS 将会再次开启 Web 应用程序。
备注及说明: 其实对于这个问题,最好的解决办法并不是基于 ASP.NET,而是另外编写一个 Windows 服务来执行这种长时间的后台任务,但是在某些条件下,如客户租用的是虚拟主机,那么采用 Windows 服务的解决方案显然不可行,一般说来虚拟主机提供商不会允许安装 Windows 服务,或者要另行收费,那么本文所叙的方法仍不失为一个好办法。