Cache的Insert 和Add 方法引发的血案

把一个简单的CMS系统拷贝到阿里云2008服务器上后,执行一个页面操作的时候,第一次操作正常,第二次或者第三次的时候,IIS就假死。查看日志:“**错误应用程序名称: w3wp.exe,版本: 7.5.7601.17514,时间戳: 0x4ce7a5f8
错误模块名称: KERNELBASE.dll,版本: 6.1.7601.19045,时间戳: 0x56258f05**”“错误存储段 ,类型 0 事件名称: APPCRASH 响应: 不可用”。

百度了一下,各种说法都有,有说权限不够的,有说程序有错误的。于是各种权限实验,还是报同样的错误。注意到其中有一条是说,程序里面有死循环所以导致溢出。联想到程序在2003下跑得欢快,而且每次都是点特定的页面第二三次,iis才crash。

开始测试数据库是否正常。自己写了和crash页面相同功能的操作,实验多次,发现不是数据库问题。那么应该是代码问题了。不过没有源码啊没有源码。没有办法只有反对编译,使用ILSpy 反编译代码。

看源代码好像没有什么问题啊,很简单,就是获取参数,然后塞入数据库。

没法子,把源代码拷贝出来,直接放在aspx运行,还是crash,把怀疑的注释掉,终于在我注释掉一个

Lib.Second.Tags.AddTagListToCache(this.siteId);

后IIS的日志里面再也没有crash了。再反编译这个方法其实是调用了一个Cache类,再反编译:

“`
public class NewsCache
{
private static object syncObj;
protected int _timeOut = 6000;
protected static volatile Cache webCache;
public int TimeOut
{
get
{
return (this._timeOut > 0) ? this._timeOut : 6000;
}
set
{
this._timeOut = ((value > 0) ? value : 6000);
}
}
public static Cache GetNewsCache
{
get
{
return NewsCache.webCache;
}
}
static NewsCache()
{
NewsCache.syncObj = new object();
NewsCache.webCache = null;
NewsCache.webCache = HttpRuntime.Cache;

        lock (NewsCache.syncObj){HttpContext current = HttpContext.Current;if (current != null){NewsCache.webCache = current.Cache;}else{NewsCache.webCache = HttpRuntime.Cache;}}}public void AddObject(string objId, object o){if (objId != null && objId.Length != 0 && o != null){CacheItemRemovedCallback cacheItemRemovedCallback = new CacheItemRemovedCallback(this.onRemove);if (this.TimeOut == 60){// if (NewsCache.webCache[objId] == null)//{NewsCache.webCache.Insert(objId, o, null, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.High, cacheItemRemovedCallback);//}}else{// if (NewsCache.webCache[objId] == null)// {NewsCache.webCache.Insert(objId, o, null, DateTime.Now.AddMinutes((double)this.TimeOut),Cache.NoSlidingExpiration, CacheItemPriority.High, cacheItemRemovedCallback);// }}}}public void onRemove(string key, object val, CacheItemRemovedReason reason){switch ((int)reason){case 1:{CacheItemRemovedCallback cacheItemRemovedCallback = new CacheItemRemovedCallback(this.onRemove);NewsCache.webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double)this.TimeOut),Cache.NoSlidingExpiration, CacheItemPriority.High, cacheItemRemovedCallback);break;}case 2:{CacheItemRemovedCallback cacheItemRemovedCallback2 = new CacheItemRemovedCallback(this.onRemove);NewsCache.webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double)this.TimeOut),Cache.NoSlidingExpiration, CacheItemPriority.High, cacheItemRemovedCallback2);break;}case 3:{CacheItemRemovedCallback cacheItemRemovedCallback3 = new CacheItemRemovedCallback(this.onRemove);NewsCache.webCache.Insert(key, val, null, DateTime.Now.AddMinutes((double)this.TimeOut),Cache.NoSlidingExpiration, CacheItemPriority.High, cacheItemRemovedCallback3);break;}}}public void RemoveObject(string objId){if (objId != null && objId.Length != 0){NewsCache.webCache.Remove(objId);}}public object RetrieveObject(string objId){object result;if (objId == null || objId.Length == 0){result = null;}else{result = NewsCache.webCache.Get(objId);}return result;}
}

值得注意的是这个Cache类Insert的时候传入的一个回掉事件,在回掉事件里面又把Cache的数据赛进去了,大概是想这个Cache永远不过期吧。

是的这个类AddObject 方法如果你多次叫用之后IIS就会挂掉,onRemove 会不挺的被调用。换句说就是对于Cache来说如果你多次调用Insert方法,而且Insert后面有回掉事件的话,这个事件就会被执行。之前的程序员在onRemove 里面又Insert了一次,于是这个onRemove 就死循环了。奇怪的是这个问题在IIS 6上并不会发生或者说在win 2003 server的IIS 6 的.Net 2.0 上并不会发生。在IIS 7 或者 7.5 的 .Net 2.0 上会发生。

当然解决的办法是把Insert换成Add,或者在Insert的时候判断一次这个Cache是否为Null。

**百度上解释的Cache 的Insert 方法是先移除再添加数据,不过msdn上没有提到insert多次会触发回掉事件。
Add 是如果有同名的键会有异常,实验证明Add有同名的也不会报错。**

最后:

ILSpy真是个好东西,反编译很棒,还免费的
Aspx文件去掉 Page language=”c#” Codebehind=”YouClass.aspx.cs” YouClass就可以把代码写到aspx文件里面动态编译,没有源代码,只要不太复制也可以搞定。

Cache的Insert 和Add 方法引发的血案相关推荐

  1. java calendar.add方法_Java Calendar add()方法与示例

    日历类add()方法add()方法在java.util包中可用. add()方法用于对指定的cal_fi(日历字段)执行相加或相减的时间量. add()方法是一个非静态方法,可通过类对象访问,如果尝试 ...

  2. 奇怪了,ADD方法会少插入字段?

    我一张表8个字段,用add方法插入,死活都是只插4个字段,在日志里显示的insert语句也是只插了4个字段,还有4个字段怎么不能插?我查了字段名称类型都没有什么问题,没插进去的有数值型也有文本型,可是 ...

  3. java的add方法的使用_Java HashSet add()方法与示例

    HashSet类add()方法add()方法在java.util包中可用. 当尚不存在给定元素时,使用add()方法将其插入此HashSet中,否则它将忽略它并返回false. add()方法是一种非 ...

  4. java日历类add方法_Java日历computeTime()方法及示例

    java日历类add方法 日历类computeTime()方法 (Calendar Class computeTime() method) computeTime() method is availa ...

  5. java日历类add方法_Java日历computeFields()方法及示例

    java日历类add方法 日历类的computeFields()方法 (Calendar Class computeFields() method) computeFields() method is ...

  6. java日历类add方法_Java日历setFirstDayOfWeek()方法与示例

    java日历类add方法 日历类setFirstDayOfWeek()方法 (Calendar Class setFirstDayOfWeek() method) setFirstDayOfWeek( ...

  7. java日历类add方法_Java日历setMinimalDaysInFirstWeek()方法与示例

    java日历类add方法 日历类setMinimalDaysInFirstWeek()方法 (Calendar Class setMinimalDaysInFirstWeek() method) se ...

  8. thinkphp中mysql添加数据_thinkphp添加数据 add()方法

    thinkphpz内置的add()方法用于向数据库表添加数据,相当于SQL中的INSERT INTO 行为 添加数据 add 方法是 CURD(Create,Update,Read,Delete / ...

  9. C# Cache何时使用及使用方法

    from:http://www.cnblogs.com/akingyao/archive/2013/01/09/2852545.html Cache 即高速缓存.那么cache是怎么样提高系统性能与运 ...

  10. java arraylist.add(),Java ArrayList add()方法与示例

    ArrayList类add()方法 语法:public boolean add(T ele); public void add(int indices, T ele);add()方法在java.uti ...

最新文章

  1. C++/C++11中std::deque的使用
  2. java终结者,动态语言是否会成为JAVA的终结者?
  3. Error-backpropagation in temporally encoded networks of spiking neurons 误差传播在时间编码的脉冲神经网络
  4. 【kafka】kafka 控制台 消费 ip 却找 域名 报错 Can‘t resolve address UnresolvedAddressException
  5. HDU 1087 Super Jumping! Jumping! Jumping!(DP)
  6. 【SpringMVC】@Controller 和 @RestController 区别
  7. k8s pod部署到不同node_应用部署演进(二)
  8. [Android][Kernel]基于crash工具搭建分析ramdump的平台
  9. Linux文件编辑常用命令
  10. C语言计算个人所得税
  11. 用Egret制作功能简单的打地鼠类游戏《冰桶挑战》
  12. python轻松生成pdf文档
  13. iOS开发中的Web应用概述
  14. (转)Android兼容8.0后APP图标变为原生小机器人图标
  15. 用topcoder准备cs 面试
  16. HDU 5183 Negative and Positive (NP) (set + 读入外挂 乱搞)
  17. 外贸企业邮箱如何撤回已发送的邮件,发错的邮件怎么撤回?
  18. 股票指标RSI背离检测程序,附代码
  19. 如何将思科路由器恢复到出厂默认设置?
  20. linux下磁盘sda,Linux下磁盘设备文件(sda,sdb,sdc….)变化的问题

热门文章

  1. 解决the application was unable to start correctly(0x000007b)与 缺少VCRUNTIME140.dll
  2. 360开源的插件化框架Replugin深度剖析
  3. css3光束_CSS3实现一束光划过图片、和文字特效
  4. Python 让书法作品和 PIL 库来一场美丽的邂逅
  5. 怎样看开源代码版权_版权声明在开源代码中泛滥成灾
  6. FFmpeg将音频、无音频的视频合并为视频
  7. 关于无线传输功率和距离的问题
  8. 微信小程序开发(7)---协同工作篇
  9. 图相似度模型(论文篇)
  10. 为web-polygraph添加user_agent和add_headers配置变量