This method is a demonstration for use of C# (csharp) Tasks and the Cache object together, to create a nice thread-safe behavior for calculations, and be efficient in the simple don't-repeat-any-action way.
public AdsFileInfo GetFileFingerPrint(string filename)
{
Log.DebugFormat("Trying to get cached file finger print for '{0}'", filename);
//First, try to get the value from the cache.
object ret = HttpRuntime.Cache.Get(filename);
if (ret != null)
{
//We got the value from the cache.
Log.DebugFormat("Got cached file finger print for '{0}'", filename);
return ((Task<AdsFileInfo>)ret).Result;
}
//Value doesn't exist in cache, create a Task object that can check the DB for it
var task = new Task<AdsFileInfo>(() => ComputeFileFingerPrint(filename));
//Try to add the task to the cache. If another thread managed to create and insert it before this thread,
//we'll fail to add it, but we will get the other task's return value.
ret = HttpRuntime.Cache.Add(filename, task, null,
DateTime.UtcNow.AddSeconds(Global.Settings.FileFingerPrintCacheDuration),
Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
if (ret == null)
{
//Successfully added to cache, meaning there wasn't a task there before
task.Start();
return task.Result;
}
Debug.Assert(ret is Task<AdsFileInfo>,
"(method GetFileFingerPrint) Cached object was supposed to be of type Task<AdsFileInfo>");
return ((Task<AdsFileInfo>)ret).Result;
}
* This source code was highlighted with Source Code Highlighter.