• asp.net中Cache的并发访问问题


    在asp.net中我们可以把我们的一些静态数据通过Cache来缓存,已提高网站性能。下面是msdn上一个使用Cache的例子。其中有可很意思的功能是

    我们可以给缓存项指定一个回调,当缓存项被remove的时候将调用回调方法通知我们。我们公司的一个应用使用了这个方法用来缓存对数据库的一些更新,来避免频繁操作数据库已提高性能。当缓存被清除的时候在调用回调吧缓存的数据集中写入数据库。这种方法当并发访问量大大时候就会出现阻塞线程的问题。从而导致cpu狂涨。最后可能耗尽所有线程池线程。

    代码
    <html>
     
    <Script runat=server language="C#">
        
    static bool itemRemoved = false;
        
    static CacheItemRemovedReason reason;
        CacheItemRemovedCallback onRemove 
    = null;

        
    public void RemovedCallback(String k, Object v, CacheItemRemovedReason r){
          itemRemoved 
    = true;
          reason 
    = r;
        }

        
    public void AddItemToCache(Object sender, EventArgs e) {
            itemRemoved 
    = false;

            onRemove 
    = new CacheItemRemovedCallback(this.RemovedCallback);

            
    if (Cache["Key1"== null)
              Cache.Add(
    "Key1""Value 1"null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.High, onRemove);
        }

        
    public void RemoveItemFromCache(Object sender, EventArgs e) {
            
    if(Cache["Key1"!= null)
              Cache.Remove(
    "Key1");
        }
     
    </Script>
     
    <body>
      
    <Form runat="server">
       
    <input type=submit OnServerClick="AddItemToCache" value="Add Item To Cache" runat="server"/>
       
    <input type=submit OnServerClick="RemoveItemFromCache" value="Remove Item From Cache" runat="server"/>
      
    </Form>
      
    <% if (itemRemoved) {
            Response.Write(
    "RemovedCallback event raised.");
            Response.Write(
    "<BR>");
            Response.Write(
    "Reason: <B>" + reason.ToString() + "</B>");
         }
         
    else {
            Response.Write(
    "Value of cache key: <B>" + Server.HtmlEncode(Cache["Key1"as string+ "</B>");
         }
      
    %>
     
    </body>
    </html>

    原因是Cache其实是个全局对象,所以对Cache的访问都会在内部通过一个ReaderWriterLock进行同步。在Remove缓存项调用回调方法的时候,由于回调方法又访问数据库。结果导致Remove缓存项长时间的占用锁,导致其他请求无法读取写入缓存,从而阻塞线程池中其他线程。所以缓存项的回调方法不适合调用长时间的操作。最好是移除缓存项后,在自己调用后续操作。避免锁定争用。

  • 相关阅读:
    用AjaxMethod 方法实现动态加载地图
    C#中HashTable的使用(转)
    ArcGIS Server 中的动态文字标注
    ArcGIS Server .Net Web ADF之几何类型的相互转换(转)
    ArcGIS Server连接远程地图服务器
    sqlplus环境配置(login.sql)
    Oracle从软件安装到运行的全流程
    【转载】linux中误删除oracle数据文件的恢复操作
    “大淘宝战略”下集市定位,将决定马云和未来淘宝的命运
    男人如何对待抱怨自己的女人
  • 原文地址:https://www.cnblogs.com/xhan/p/1782230.html
Copyright © 2020-2023  润新知