简体   繁体   中英

ASP.net Caching

I have implemented asp.net caching. But I am getting weird results

Unlike most caching where you are trying to avoid the amount of hits to the DB. I am trying to avoid any hits to the DB by the user. This is b/c the amount of time the fist page takes to load. It is basically a dashboard with a lot of charts and long running queries

I tried several techniques 1) Have the cache time very long and have a schedule process expire and get new cache. 2) and on RemoveCallback

In the second option I have all the cache go through a static class I created. The purpose is as it expires to refresh the data. Here is what I am calling.

Cache.Insert(dbCacheString, dtNetwork, null, DateTime.Now.AddHours(2),
    System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High, 
    new CacheItemRemovedCallback(CacheManager.CacheRemovedCallback));

    public static class CacheManager
    {
        private static Hashtable times = new Hashtable();
        private static bool isRefreshingCache = false;

        public static void CacheRemovedCallback(String key, object value,
            CacheItemRemovedReason removedReason)
        {
            RefreshCache(key);
        }

        public static void StartCache()
        {
            string lcUrl = "http://localhost/ratingspage/";
            // *** Establish the request 

            try
            {

                WebClient client = new WebClient();
                client.Credentials = new NetworkCredential("xxx", "xxx", 
                    "xxx");
                byte[] myDataBuffer = client.DownloadData(lcUrl);


            }
            catch (Exception ex)
            {
                ErrHandler.WriteError(ex.Message + "\n" + 
                    ex.StackTrace.ToString());
                LogUtil.LogDebugMessages(ex.Message + ":" + 
                    ex.StackTrace.ToString());
            }

        }

        public static void RefreshCache(string key)
        {
            string controlname = "";
            if ( key.ToLower().StartsWith("control:") )
            {
                string[] tmp = key.Split(':');
                if (tmp.Length > 1)
                    controlname = tmp[1];
                else
                    return;
            }
            else
                return;

            string lcUrl = "http://localhost/ratingspage/Admin/" + "
                "LoadControl.aspx?CachingSpider=true&Control=" + controlname;
            string lcHtml = isRefreshingCache.ToString();
            // *** Establish the request 

            if (!isRefreshingCache)
            {

                isRefreshingCache = true;
                lcHtml = isRefreshingCache.ToString();
                try
                {

                    WebClient client = new WebClient();
                    client.Credentials = new NetworkCredential("xxx", 
                        "xxx", "xxx");
                    byte[] myDataBuffer = client.DownloadData(lcUrl);
                    lcHtml = Encoding.ASCII.GetString(myDataBuffer);

                }
                catch (Exception ex)
                {
                    lcHtml = ex.Message;
                    isRefreshingCache = false;
                    ErrHandler.WriteError(ex.Message + "\n" + 
                        ex.StackTrace.ToString());
                    LogUtil.LogDebugMessages(ex.Message + ":" + 
                        ex.StackTrace.ToString());
                }
                isRefreshingCache = false;
            }



            MailMessage mail = new MailMessage(
                new MailAddress("jgiblin@univision.net"), 
                new MailAddress("jgiblin@univision.net"));
            mail.Subject = "Cache Expire: " + key;
            mail.Body = string.Format("The Key {0} has expired at {1}", 
                key, DateTime.Now.ToShortDateString() + " " +
                DateTime.Now.ToShortTimeString()) + "\nRefreshing Cache: " + 
                lcHtml;
            SmtpClient smtp = new SmtpClient("mercury.utg.uvn.net");
            mail.IsBodyHtml = false;
            try
            {

                smtp.Send(mail);

            }
            catch (Exception ex)
            {
                ErrHandler.WriteError(ex.Message + "\n" + 
                    ex.StackTrace.ToString());
                LogUtil.LogDebugMessages(ex.Message + ":" + 
                    ex.StackTrace.ToString());
            }

        }
    }

for some reason, when I go to the page. Someone times the data is cached and sometimes it is not. Is there something wrong here

I tried app fabric but since the server does not have iis 7 I am not able to use that

The amount of data you can get into the cache may be the issue.

If the cache is full then the data will obviously not be cached.

You can check your memory allocation using the process monitor , have a look in "Cache Total Entries."

Looks to me like you may have a race condition in your RefreshCache call. Check out this great answer for suggestions on how to handle synchronization:

C# version of java's synchronized keyword?

If I were you, I'd simplify my code. You only really need:

  1. when the application starts up, load the cache
  2. when the cache expires, reload it
  3. if a user tries to access the cached object and misses, sleep their thread for a second and check again

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM