在前天,本人刚下了discuzNT 的代码,研究了些许时间
老是报stackoverflow的error
在web.config中发现了这段代码:
<httpModules>
<add type="Discuz.Forum.HttpModule, Discuz.Forum" name="HttpModule"/>
</httpModules>
呵呵,就是HttpModule类,好,找到HttpModule.cs,打开
在Line48 有这么一句
if (Utils.InArray(Utils.GetCookie("dnttemplateid"), TemplateFactory.GetValidTemplateIDList()))
在执行TemplateFactory.GetValidTemplateIDList()的时候老实报错,就找到在打开
发现在执行
cacheService.AddObject("/Forum/TemplateIDList", str);的时候还是报错
接着进去,这是他的具体的方法体
public virtual void AddObject(string xpath, string str)
{
lock (lockHelper)
{
if ((str != null) && (str != ""))
{
this.AddObject(xpath + "flag", CacheFlag.CacheHaveData);
}
else
{
this.AddObject(xpath + "flag", CacheFlag.CacheNoData);
}
this.AddObject(xpath, str);
}
}
在情况对的时候,首先会进去 this.AddObject(xpath + "flag", CacheFlag.CacheHaveData);
这时候调用的是public virtual void AddObject(string xpath, object o)这个方法,这个方法是没问题的,就是将一些数据插入Cache里面
调用完成之后就执行的是 this.AddObject(xpath, str);(public virtual void AddObject(string xpath, string str)
)
大家注意,调用的是自身,是递归
好,前面的if-else在执行一遍,回到this.AddObject(xpath, str);还是递归
我就他的意思应该是首先插入路径,然后插入实际数据,两次缓存数据,但是实际代码就是这样子
为了证明我的想法,我把代码加成这个样子
int i=0;
public virtual void AddObject(string xpath, string str)
{
i++;//计数功能
lock (lockHelper)
{
if ((str != null) && (str != ""))
{
this.AddObject(xpath + "flag", CacheFlag.CacheHaveData);
}
else
{
this.AddObject(xpath + "flag", CacheFlag.CacheNoData);
}
this.AddObject(xpath, str);
}
}
再次运行,再次报错,一看i达到了2049,Cache给插入了2000多次,怪不得会overflow
考虑了一下,改代码如下:
public virtual void AddObject(string xpath, string str)
{
lock (lockHelper)
{
if ((str != null) && (str != ""))
{
this.AddObject(xpath + "flag", CacheFlag.CacheHaveData);
}
else
{
this.AddObject(xpath + "flag", CacheFlag.CacheNoData);
}
this.AddObject(xpath, (object)str);
}
}
在第二次的时候box一下,就直接进入public virtual void AddObject(string xpath, string str)里了
这个DNTCache里好多这样的AddObject方法,都是这样的错误
至此,运行暂时没问题了
不知道大家遇到了这种情况没?
不排除是我的反编工具出的错 ,我的平台是win2003sp2+sqlserver2005EEsp2+vstssp1