小菜又开始做梦了....睡的好香...
想起了昨天老大交待的事.在修改DNT.config配置文件中的配置项时,程序无法检测到配置文件已经被修改.
小菜沉思了一会儿,想到了解决方案,使用一个定时器Timer,每隔一段时间让它重新加载一下基本配置描述类.
using System;
using System.IO;
using System.Web;
using System.Xml.Serialization;

namespace Discuz.Config


{

/**//// <summary>
/// 基本配置文件管理类
/// </summary>
public class BaseConfigFileManager

{
private static BaseConfigInfo m_configInfo; //基本配置信息描述对象
private static string m_configFilePath; //基本配置文件路径
private static System.Timers.Timer timer = new System.Timers.Timer(); //定时器

static BaseConfigFileManager()

{
m_configInfo = DeserializeInfo();

timer.Enabled = true; //该值指示 Timer 是否应引发 Elapsed 事件
timer.Interval = 15000; //获取或设置引发 Elapsed 事件的间隔 1.5秒
timer.AutoReset = true; //该值指示 Timer 是应在每次指定的间隔结束时引发 Elapsed 事件,还是仅在指定的间隔第一次结束后引发该事件
timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
timer.Start(); //通过将 Enabled 设置为 true 开始引发 Elapsed 事件
}


/**//// <summary>
/// 每隔1.5秒重新加载基本配置描述信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{
m_configInfo = DeserializeInfo();
}


/**//// <summary>
/// 基本配置文件路径
/// </summary>
private static string ConfigFilePath

{
get

{
if (m_configFilePath == null)

{
HttpContext context = HttpContext.Current;
m_configFilePath = context.Server.MapPath("~/DNT.config");
}

return m_configFilePath;
}
}


/**//// <summary>
/// 返回基本配置文件信息描述对象
/// </summary>
private static BaseConfigInfo GetBaseConfig

{
get

{
return m_configInfo;
}
}


/**//// <summary>
/// 返回数据库类型
/// </summary>
public static string GetDbType

{
get

{
return GetBaseConfig.DbType;
}
}


/**//// <summary>
/// 反序列化基本配置信息描述类
/// </summary>
/// <returns></returns>
private static BaseConfigInfo DeserializeInfo()

{
BaseConfigInfo configInfo;
FileStream fs = null;
try

{
fs = new FileStream(ConfigFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(typeof(BaseConfigInfo));
configInfo = (BaseConfigInfo)serializer.Deserialize(fs);
}
catch (Exception ex)

{
throw ex;
}
finally

{
if (fs != null)
fs.Close();
}

return configInfo;
}
}
}

小菜马上对这个解决方案进行了测试Response.Write(Discuz.Config.BaseConfigFileManager.GetDbType);运行...
看到的是SqlServer.然后把DNT.config配置文件中的<DbType>SqlServer</DbType>
修改为<DbType>Access</DbType>
等待1.5秒,然后刷新了下页面,显示Access...哈哈...成功啦...
老大这时走了过来,看小菜的任务完成了如何,看了下代码.问到ConfigFilePath是否需要改成如下这种形式.

/**//// <summary>
/// 基本配置文件路径
/// </summary>
private static string ConfigFilePath


{
get

{
if (m_configFilePath == null)

{
HttpContext context = HttpContext.Current;
if (context != null)

{
m_configFilePath = context.Server.MapPath("~/DNT.config");
}
else

{
m_configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DNT.config");
}
}

return m_configFilePath;
}
}
小菜想了想,老大的这段代码和自己的有何不同.
唯一的差别就在于if(context!=null){/*来自Web的请求*/}else{/*不是来自Web的请求*/}
什么情况下会出现不是来自Web的请求呢? 当请求是由Web服务器自己发出的时候.
在我们的代码中是否会出现这种情况呢? 确实会出现,小菜使用定时器每隔1.5秒就引发了Elapsed事件.
处理代码是Timer_Elapsed-----间接就是--------m_configInfo = DeserializeInfo();
而DeserializeInfo()中又用到了ConfigFilePath所以,也就是说是应该使用老大说的代码...
可是小菜又想了,我刚才没有用老大的代码也一样正确的运行啊,这是什么原因呢?
因为第一次请求是来自Web的请求,为m_configFilePath赋值,它又是static类型,一直保存着,隔了1.5秒Timer_Elapsed中的代码被执行.使用到ConfigFilePath属性时,由于m_configFilePath不为null所以if(m_configFilePath!=null){/*这里不会被执行到了*/} 而是直接return m_configFilePath
所以说老大说的代码不是必须的......老大满意的点点头...
老大对小菜的工作感到挺满意.不过老大为了培养小菜,提出了更高的要求了.
小菜啊!你看你的代码,你每隔1.5秒,就取一次BaseConfigInfo.如果我一年没有修改这个DNT.config配置文件,你这一年时间内取了多少次BaeConfigInfo啊....小菜算了下,一年=365天=365*24小时=365*24*60分钟=365*24*60*60/1.5次
天呐,这数字真恐怖...
小菜赶紧跑回去修改代码了....小菜想到了解决方法了..通过System.IO.File.GetLastWriteTime(ConfigFilePath)
就可以得到最后修改文件的时间了,如果这个时间与新的最后修改文件的时间相同时,就表示该配置文件没有被修改..好,行动
using System;
using System.IO;
using System.Web;
using System.Xml.Serialization;

namespace Discuz.Config


{

/**//// <summary>
/// 基本配置文件管理类
/// </summary>
public class BaseConfigFileManager

{
private static BaseConfigInfo m_configInfo; //基本配置信息描述对象
private static string m_configFilePath; //基本配置文件路径
private static System.Timers.Timer timer = new System.Timers.Timer(); //定时器
private static DateTime m_fileOldChange; //基本配置文件最后修改时间

static BaseConfigFileManager()

{
m_configInfo = LoadConfig(false);
m_fileOldChange = File.GetLastWriteTime(ConfigFilePath);

timer.Enabled = true; //该值指示 Timer 是否应引发 Elapsed 事件
timer.Interval = 15000; //获取或设置引发 Elapsed 事件的间隔 1.5秒
timer.AutoReset = true; //该值指示 Timer 是应在每次指定的间隔结束时引发 Elapsed 事件,还是仅在指定的间隔第一次结束后引发该事件
timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
timer.Start(); //通过将 Enabled 设置为 true 开始引发 Elapsed 事件
}


/**//// <summary>
/// 每隔1.5秒重新加载基本配置描述信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{
LoadConfig(true);
}


/**//// <summary>
/// 加载(反序列化)基本配置信息描述对象
/// </summary>
/// <param name="checkTime">是否检查并更新传递进来的"文件加载时间"变量</param>
/// <returns></returns>
protected static BaseConfigInfo LoadConfig(bool checkTime)

{
if (checkTime)

{
DateTime m_fileNewChange = File.GetLastWriteTime(ConfigFilePath);
if (m_fileOldChange != m_fileNewChange)

{
m_fileOldChange = m_fileNewChange;

m_configInfo = DeserializeInfo();
}
}
else

{
m_configInfo = DeserializeInfo();
}

return m_configInfo;
}


/**//// <summary>
/// 基本配置文件路径
/// </summary>
private static string ConfigFilePath

{
get

{
if (m_configFilePath == null)

{
HttpContext context = HttpContext.Current;
m_configFilePath = context.Server.MapPath("~/DNT.config");
}

return m_configFilePath;
}
}


/**//// <summary>
/// 返回基本配置信息描述对象
/// </summary>
private static BaseConfigInfo GetBaseConfig

{
get

{
return m_configInfo;
}
}


/**//// <summary>
/// 返回数据库类型
/// </summary>
public static string GetDbType

{
get

{
return GetBaseConfig.DbType;
}
}


/**//// <summary>
/// 反序列化基本配置信息描述类
/// </summary>
/// <returns></returns>
private static BaseConfigInfo DeserializeInfo()

{
BaseConfigInfo configInfo;
FileStream fs = null;
try

{
fs = new FileStream(ConfigFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(typeof(BaseConfigInfo));
configInfo = (BaseConfigInfo)serializer.Deserialize(fs);
}
