Discuz 论坛的 Discuz.Cache.DNTCache 的AddObject () 死循环的解决办法

  本文来自:  http://nt.discuz.net/showtopic.aspx?topicid=15237&onlyauthor=1
   谢谢作者给我解决了大难题!

我也来提交个bug

在前天,本人刚下了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

你可能感兴趣的:(object)