У меня есть метод расширения для объекта Microsoft.ApplicationServer.Caching.DataCache, найденного в Windows Server AppFabric SDK, который выглядит следующим образом:
using System;
using System.Collections.Generic;
using Microsoft.ApplicationServer.Caching;
namespace Caching
{
public static class CacheExtensions
{
private static Dictionary<string, object> locks = new Dictionary<string, object>();
public static T Fetch<T>(this DataCache @this, string key, Func<T> func)
{
return @this.Fetch(key, func, TimeSpan.FromSeconds(30));
}
public static T Fetch<T>(this DataCache @this, string key, Func<T> func, TimeSpan timeout)
{
var result = @this.Get(key);
if (result == null)
{
lock (GetLock(key))
{
result = @this.Get(key);
if (result == null)
{
result = func();
if (result != null)
{
@this.Put(key, result, timeout);
}
}
}
}
return (T)result;
}
private static object GetLock(string key)
{
object @lock = null;
if (!locks.TryGetValue(key, out @lock))
{
lock (locks)
{
if (!locks.TryGetValue(key, out @lock))
{
@lock = new object();
locks.Add(key, @lock);
}
}
}
return @lock;
}
}
}
Цель состоит в том, чтобы позволить разработчику написать код, который говорит: «Извлеките мне некоторые данные, сначала попробовав кеш. Если они недоступны в кеше, выполните указанную функцию, поместите результаты в кеш для следующего вызывающего, а затем верните Результаты". Как это:
var data = dataCache.Fetch("key", () => SomeLongRunningOperation());
Ограничения блокировок при выполнении потенциально долго выполняющегося вызова функции для одного потока, но только внутри одного процесса на одном компьютере. Как бы вы расширили этот шаблон, чтобы распределить блокировку, чтобы предотвратить одновременное выполнение этой функции несколькими процессами / машинами?