65.9K
CodeProject is changing. Read more.
Home

Simple Client Side WCF Caching

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.62/5 (6 votes)

Jan 31, 2008

CPOL

2 min read

viewsIcon

37934

downloadIcon

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:

 // 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:

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