核心提示:
IIS 7 的集成模式在 设计上发生了变化,Application_Start 事件中,HttpContext.Current 是未被初始化的。
(原文链接 http://ddbiz.com/?p=139)
如下的.asax 代码在IIS 6 中运行正常,但在 IIS 7的集成模式下,是无效的[加粗部分]
void Application_Start(object sender, EventArgs e)
{
//在应用程序启动时运行的代码
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~/bin/log4net.config")));
ILog log = LogManager.GetLogger("web");
log.Info("Application Started");
string hostname = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
Int32 checkInterval = new ServiceFactory().GetSiteService().Setting4EmailCheckInterval(hostname);
emailTimer = new Timer(new TimerCallback(ScheduleEmailSender),
hostname,
2 * 60 * 1000, //系统启动可能需要1分钟时间,初始化很慢,此处使用2分钟设定
checkInterval * 1000);
*/
}
相似的,Application_Start 在IIS 7的集成模式下, Context, Application, Session 都是未初始化的。因此要实现原来的功能,只有两种方式:
1. IIS 7 运行在兼容的经典模式下
2. 原来的初始化放在 Application_BeginRequest 中。如上面的代码,修改成如下:
void Application_BeginRequest()
{
FirstRequestInitialization.Initialize(Context);
......
}
internal class FirstRequestInitialization
{
private static bool s_InitializedAlready = false;
private static Object s_lock = new Object();
private static Timer scheduleTimer = null;
// Initialize only on the first request
public static void Initialize(HttpContext context)
{
if (s_InitializedAlready)
{
return;
}
lock (s_lock)
{
if (s_InitializedAlready)
{
return;
}
string hostname = context.Request.ServerVariables["SERVER_NAME"];
Int32 checkInterval = new ServiceFactory().GetSiteService().Setting4EmailCheckInterval(hostname);
emailLoger.InfoFormat("{0}, Starting schedule email sender checker, interval={1}", DateTime.Now, checkInterval);
scheduleTimer = new Timer(new TimerCallback(ScheduleEmailSender),
hostname,
2 * 60 * 1000, //系统启动可能需要1分钟时间,初始化很慢,此处使用2分钟设定
checkInterval * 1000);
// Perform first-request initialization here ...
s_InitializedAlready = true;
}
}
(原文链接 http://ddbiz.com/?p=139)