Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Simple Client Side WCF Caching

3.62/5 (6 votes)
31 Jan 2008CPOL2 min read 1   348  
Implementing client side caching for WCF

Introduction

When using the Windows Communication Framework (WCF) or Remoting, one of the issues developers have to deal with is degraded performance because of chatty interfaces. To deal with this, I have developed a method to store data that is generally static on the client to reduce calls to the server side for this data. The key to the method is that your objects and WCF calls do not need to know about this caching, it is all done in the WCF client code right before a call to the server is made.

I will demonstrate this method with a simple WCF application that pulls data from the Categories table of Northwind and caches these categories on the client side. When a call is made to retrieve the category by id, it does not have to make a call to the server, it can just pull the data from the client side cache.

Note: I came up with this solution while working to improve performance in a WinForms (Smart Client) application that was experiencing performance problems. I found the root cause of the performance issues to be too many calls to the database. The original implementation was done with Remoting rather than WCF.

Using the Code

This method involves using a Singleton to store the data on the client side. Data in the Singleton is accessed using events in the WCF client because the client is in a different project than the Singleton.

To enable the client to retrieve data from the client side cache, check to see if the event is not null and then fire the event using the custom event args containing the search parameter and also containing a way to pass the result back. If the object is not found locally, then the client will make a call to the server to find it there.

The WCF Client method to find the Category by an Id:

C#
// Event to hook up in the Singleton that will get the data from the local store
   public event FindObjectByIdInvokedDelegate GetCategoryByIdInvoked;

   public Category GetCategoryById(int id)
   {
     Category cat = null;

     // Check to see if the event is hooked up
     if (GetCategoryByIdInvoked != null)
     {
       // Create the event args with the id of the requested object
       FindObjectByIdEventArgs args = new FindObjectByIdEventArgs(id);
       // Fire the event to look up the data
       GetCategoryByIdInvoked(this, args);
       // Get the object that was found, if no object is found this should return null
       cat = args.FoundObject as Category;

     }

     // If nothing was found locally, then go to the server
     // to find the object from the database
     if (cat == null)
     {
       cat = base.Channel.GetCategoryById(id);
     }

     return cat;
   }

The Singleton class with WCF client event hooked up:

C#
public Client WcfClient
{
  get{
    if (wcfClient == null)
    {
      // Create new instance of the Client if necessary
      wcfClient = new Client();
      // Hook up event in the Client to find a category by an Id
      wcfClient.GetCategoryByIdInvoked += 
	    new FindObjectByIdInvokedDelegate(wcfClient_GetCategoryByIdInvoked);
    }
    return wcfClient;
  }
}

void wcfClient_GetCategoryByIdInvoked(object sender, FindObjectByIdEventArgs args)
{
  // Look in the locally stored collection of Categories 
  // to find the specific category
  foreach (Category cat in Categories)
  {
    // If we find the category then set the result in the 
    // event args to get passed back to the Client class
    if (cat.CategoryID == args.SubjectId)
      args.FoundObject = cat;
  }
}

Conclusion

This is a pretty simple example, but this can be expanded fairly easily to include any type of data. By doing this in a large smart client application, we saw huge performance increases by reducing calls to the server. I would highly recommend anyone looking to increase performance in a smart client application to look into implementing a process similar to this.

History

  • 1/31/2008 - Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)