locked
Caching WCF Service RRS feed

  • Question

  • I am using WCF service in Silverlight 2.0.

    How can I use the caching functionality to the service?

    Any help regarding the same is highly appreciable.

     

    Monday, March 23, 2009 10:57 AM

Answers

  • What are the things you want to cache? I'm using the ASP.NET Caching most of the time. But there are a lot of different caching mechanisms like distributed cache (NCache). But you can even use a static variable (Synchronize the access to it).

    You can access the ASP.NET Cache in WCF by using HttpRuntime.Cache. You'll need to add a reference to System.Web however. But I guess this isn't a problem.

    If you want more detailed information please provide some information about the things you want to cache, and why you want to cache it.
    Monday, March 23, 2009 3:50 PM
  • Alright, that's something different. I would do this with a local variable containing a IDictionary<string,CacheItem> cache. Something like that. I would implement CacheItem with a object (containing the data), a datetime for creationdatetime and a timespan for timetokeep in cache. I would implement a method to check if the cacheitem is still valid.

    Something like this (please test it thoroughly) for in memory cache.

     

    public class Cache
    {
    private readonly IDictionary<string, CacheItem> cacheItems = new Dictionary<string, CacheItem>();
    private Cache() {}

    public void Add(string key, CacheItem value)
    {
    cacheItems.Add(key, value);
    }

    public CacheItem this[string key]
    {
    get
    {
    if (cacheItems.ContainsKey(key))
    {
    CacheItem ci = cacheItems[key];
    if(ci.IsValid())
    return cacheItems[key];

    cacheItems.Remove(key);
    }
    return null;
    }
    set { cacheItems[key] = value; }
    }

    public bool Remove(string key)
    {
    return cacheItems.Remove(key);
    }

    public static Cache Current = new Cache();
    }

    public class CacheItem
    {
    private readonly DateTime creationDate = DateTime.Now;
    private readonly TimeSpan validDuration;

    public CacheItem(TimeSpan validDuration, object data)
    {
    this.validDuration = validDuration;
    Data = data;
    }

    public object Data { set; private get; }
    public T GetData() where T : class
    {
    return Data as T;
    }

    public bool IsValid()
    {
    return creationDate.Add(validDuration) > DateTime.Now;
    }
    }

      And you can use this as simple as:

      

    //Put something in the cache.
    User user = new User();
    Cache.Current.Add("currentUser",new CacheItem(TimeSpan.FromMinutes(2),user));

    //Retrieve something out of the cache.
    if (Cache.Current["currentUser"] != null)
    user = Cache.Current["currentUser"].GetData();
     
    Tuesday, March 24, 2009 4:05 AM

All replies

  • What are the things you want to cache? I'm using the ASP.NET Caching most of the time. But there are a lot of different caching mechanisms like distributed cache (NCache). But you can even use a static variable (Synchronize the access to it).

    You can access the ASP.NET Cache in WCF by using HttpRuntime.Cache. You'll need to add a reference to System.Web however. But I guess this isn't a problem.

    If you want more detailed information please provide some information about the things you want to cache, and why you want to cache it.
    Monday, March 23, 2009 3:50 PM
  • Actually, I want to cache the WCF service objects & their respective data. So, within the cached time duration if I call the service again ... it should not go to the server. It will load the data from the local cache itself. Let me know.... how I can achieve this in Silverlight 2.

    Tuesday, March 24, 2009 12:14 AM
  • Alright, that's something different. I would do this with a local variable containing a IDictionary<string,CacheItem> cache. Something like that. I would implement CacheItem with a object (containing the data), a datetime for creationdatetime and a timespan for timetokeep in cache. I would implement a method to check if the cacheitem is still valid.

    Something like this (please test it thoroughly) for in memory cache.

     

    public class Cache
    {
    private readonly IDictionary<string, CacheItem> cacheItems = new Dictionary<string, CacheItem>();
    private Cache() {}

    public void Add(string key, CacheItem value)
    {
    cacheItems.Add(key, value);
    }

    public CacheItem this[string key]
    {
    get
    {
    if (cacheItems.ContainsKey(key))
    {
    CacheItem ci = cacheItems[key];
    if(ci.IsValid())
    return cacheItems[key];

    cacheItems.Remove(key);
    }
    return null;
    }
    set { cacheItems[key] = value; }
    }

    public bool Remove(string key)
    {
    return cacheItems.Remove(key);
    }

    public static Cache Current = new Cache();
    }

    public class CacheItem
    {
    private readonly DateTime creationDate = DateTime.Now;
    private readonly TimeSpan validDuration;

    public CacheItem(TimeSpan validDuration, object data)
    {
    this.validDuration = validDuration;
    Data = data;
    }

    public object Data { set; private get; }
    public T GetData() where T : class
    {
    return Data as T;
    }

    public bool IsValid()
    {
    return creationDate.Add(validDuration) > DateTime.Now;
    }
    }

      And you can use this as simple as:

      

    //Put something in the cache.
    User user = new User();
    Cache.Current.Add("currentUser",new CacheItem(TimeSpan.FromMinutes(2),user));

    //Retrieve something out of the cache.
    if (Cache.Current["currentUser"] != null)
    user = Cache.Current["currentUser"].GetData();
     
    Tuesday, March 24, 2009 4:05 AM
  • Thanks for your response.

    I will check it out..... :)

    Tuesday, March 24, 2009 4:30 AM
  • I have several objects that are small and frequently used, so I load each on startup using WCF and put it in a static variable.  At this stage of development, there is no checking that the items are actually loaded, and occasionally the application will try to access something before it has been loaded.

    For example, if a page tries to bind a UI element to one of these objects and happens to request it too soon, nothing will be displayed.  This is rare, but it can happen.

    What is the best way to wait for an object from WCF if it is not yet available when needed, or defer display until the data is loaded.

    Can I use a WaitHandle?  Or what?

    Thanks in advance for your suggestions.

    Monday, October 18, 2010 11:52 PM