3

I have a static method in a helper class named helper.getdiscount(). This class is ASP.NET frontend code and used by UI pages.

Inside this method I check if some data is in the ASP.NET cache then return it, otherwise it makes a service call and store the result in the cache and then returns that value.

Will this be a problem considering multiple threads might be accessing it at the same time?

if (HttpContext.Current.Cache["GenRebateDiscountPercentage"] == null)
{ 
    IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
    rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;


    if (rebateDiscountPercentage > 0)
    {
        HttpContext.Current.Cache.Add("GenRebateDiscountPercentage", rebateDiscountPercentage, null, DateTime.Now.AddDays(1), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
    }
}
else
{      
    decimal.TryParse(HttpContext.Current.Cache["GenRebateDiscountPercentage"].ToString(), out rebateDiscountPercentage);
}

Please advise if this is fine or any better approach could be used.

Erik Schierboom
  • 16,301
  • 10
  • 64
  • 81
krishnakumar
  • 617
  • 1
  • 6
  • 22
  • The simple solution would be to use a lock, with which you can ensure that only one thread accesses the code. There is another stackoverflow question that is similar to your question: http://stackoverflow.com/questions/4413001/locking-an-asp-net-application-variable – Erik Schierboom Jun 11 '13 at 12:49

2 Answers2

0

try something like this with lock object.

static readonly object objectToBeLocked= new object();

        lock( objectToBeLocked)
        { 
             if (HttpContext.Current.Cache["GenRebateDiscountPercentage"] == null)
            { 
                IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
                rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;


                if (rebateDiscountPercentage > 0)
                {
                    HttpContext.Current.Cache.Add("GenRebateDiscountPercentage", rebateDiscountPercentage, null, DateTime.Now.AddDays(1), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
                }
            }
            else
            {      
                decimal.TryParse(HttpContext.Current.Cache["GenRebateDiscountPercentage"].ToString(), out rebateDiscountPercentage);
            }
        }

Also you can look into following thread.

What is the best way to lock cache in asp.net?

Community
  • 1
  • 1
Jalpesh Vadgama
  • 13,653
  • 19
  • 72
  • 94
0

Use these generic methods to use the cache for any type:

`public static void AddCache(string key, object Data, int minutesToLive = 1440)
{
    if (Data == null)
        return;
    HttpContext.Current.Cache.Insert(key, Data, null, DateTime.Now.AddMinutes(minutesToLive), Cache.NoSlidingExpiration);
}

public static T GetCache<T>(string key)
{
    return (T)HttpContext.Current.Cache.Get(key);
} `

Now to solve your problem:

`if(GetCache<decimal>("GenRebateDiscountPercentage") == null)
{ 

   IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
   rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;


   if (rebateDiscountPercentage > 0)
   {
       AddCache("GetGenRebateDiscountPercentage", rebateDiscountPercentage);
   }
}
else
{
    rebateDiscountPercentage = GetCache<decimal>("GetGenRebateDiscountPercentage");
}

`

Zee
  • 622
  • 4
  • 13