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
);
very good article thanks for sharing it
ReplyDelete