SharePoint SPList Cache Dependency

When working customized solutions i SharePoint caching custom objects may be a good idea. The standard ASP.net cahce i commonly used with a expiry time specified in seconds or minutes depending on how “fresh” the data needs to be. Objects cached in a customized SharePoint solution are often representations of content within SharePoint lists. In that case a cache dependency against the SharePoint resource might be a good idea.

I´m going to show how to create a custom cache dependency class that adds dependency to a list.

The custom implementation in SPListCacheDependency is set up to check a list for changes every ten seconds. The class can be modified to monitor other SharePoint resources as well.

public class SPListCacheDependency : CacheDependency

{

private readonly SPListCacheDependencyEventArgs _eventArgs;

private readonly Timer _timer;

private readonly DateTime _lastModified;

private readonly int _itemCount;

private readonly string _uniqueId;

public SPListCacheDependency(SPList list)

{

_lastModified = list.LastItemModifiedDate;

if (list.LastItemDeletedDate > _lastModified)

{

_lastModified = list.LastItemDeletedDate;

}

_itemCount = list.ItemCount;

_uniqueId = list.ID.ToString() + list.ParentWeb.ID + list.ParentWeb.Site.ID;

_eventArgs = new SPListCacheDependencyEventArgs(list.ParentWeb.Site.ID, list.ParentWeb.ID, list.ID);

_timer = new Timer(10000) { AutoReset = true }; // check every ten second

_timer.Elapsed += MonitorChanges;

_timer.Start();

}

public override string GetUniqueID()

{

return _uniqueId;

}

public bool HasObjectChanged(object source)

{

SPList list = (SPList)source;

DateTime modified = list.LastItemModifiedDate;

if (list.LastItemDeletedDate > modified)

modified = list.LastItemDeletedDate;

return _lastModified != modified || _itemCount != list.ItemCount;

}

private void MonitorChanges(object sender, ElapsedEventArgs e)

{

try

{

using (SPSite site = new SPSite(_eventArgs.SiteId))

{

using (SPWeb web = site.OpenWeb(_eventArgs.WebId))

{

SPList list = web.Lists[_eventArgs.ListId];

ObjectChanged(list);

}

}

}

catch (ArgumentException)

{

//Object has been deleted.

ObjectChanged(null);

}

}

/// <summary>

/// Raise event and stop timer if object has been updated

/// </summary>

/// <param name="item"></param>

private void ObjectChanged(object item)

{

if (!HasObjectChanged(item) && item != null) return;

_timer.Stop();

NotifyDependencyChanged(this, _eventArgs);

}

}

/// <summary>

/// Information holding object for a SharePoint List cache dependency object.

/// </summary>

internal class SPListCacheDependencyEventArgs : EventArgs

{

public SPListCacheDependencyEventArgs(Guid siteId, Guid webId, Guid listId)

{

SiteId = siteId;

WebId = webId;

ListId = listId;

}

public Guid SiteId { get; private set; }

public Guid WebId { get; private set; }

public Guid ListId { get; private set; }

}

The usage of the class SPListCacheDependency is simply:

 

HttpContext.Current.Cache.Add("MyCacheKey",

myObjectsToCache,

new SPListCacheDependency(MySPList),

System.Web.Caching.Cache.NoAbsoluteExpiration,

System.Web.Caching.Cache.NoSlidingExpiration,

CacheItemPriority.Normal,

null);

Comments

  1. very good article thanks for sharing it

    ReplyDelete

Post a Comment