আমি ধরে নিই এই কোডটিতে সামঞ্জস্যপূর্ণ সমস্যা রয়েছে:
const string CacheKey = "CacheKey";
static string GetCachedData()
{
string expensiveString =null;
if (MemoryCache.Default.Contains(CacheKey))
{
expensiveString = MemoryCache.Default[CacheKey] as string;
}
else
{
CacheItemPolicy cip = new CacheItemPolicy()
{
AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(20))
};
expensiveString = SomeHeavyAndExpensiveCalculation();
MemoryCache.Default.Set(CacheKey, expensiveString, cip);
}
return expensiveString;
}
সম্মতিযুক্ত ইস্যুর কারণ হ'ল একাধিক থ্রেড একটি নাল কী পেতে পারে এবং তারপরে ক্যাশে ডেটা toোকানোর চেষ্টা করতে পারে।
এই কোড একত্রীকরণের প্রমাণ তৈরি করার সবচেয়ে সংক্ষিপ্ততম এবং পরিষ্কার উপায় কী হবে? আমি আমার ক্যাশে সম্পর্কিত কোড জুড়ে একটি ভাল প্যাটার্ন অনুসরণ করতে চাই। একটি অনলাইন নিবন্ধের একটি লিঙ্ক একটি দুর্দান্ত সাহায্য হবে।
হালনাগাদ:
আমি @ স্কট চেম্বারলাইনের উত্তরের ভিত্তিতে এই কোডটি নিয়ে এসেছি। কেউ কি এর সাথে কোনও পারফরম্যান্স বা সম্মতিযুক্ত সমস্যা খুঁজে পেতে পারেন? যদি এটি কাজ করে, এটি কোড এবং ত্রুটির অনেক লাইন সংরক্ষণ করবে।
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Caching;
namespace CachePoc
{
class Program
{
static object everoneUseThisLockObject4CacheXYZ = new object();
const string CacheXYZ = "CacheXYZ";
static object everoneUseThisLockObject4CacheABC = new object();
const string CacheABC = "CacheABC";
static void Main(string[] args)
{
string xyzData = MemoryCacheHelper.GetCachedData<string>(CacheXYZ, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
string abcData = MemoryCacheHelper.GetCachedData<string>(CacheABC, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
}
private static string SomeHeavyAndExpensiveXYZCalculation() {return "Expensive";}
private static string SomeHeavyAndExpensiveABCCalculation() {return "Expensive";}
public static class MemoryCacheHelper
{
public static T GetCachedData<T>(string cacheKey, object cacheLock, int cacheTimePolicyMinutes, Func<T> GetData)
where T : class
{
//Returns null if the string does not exist, prevents a race condition where the cache invalidates between the contains check and the retreival.
T cachedData = MemoryCache.Default.Get(cacheKey, null) as T;
if (cachedData != null)
{
return cachedData;
}
lock (cacheLock)
{
//Check to see if anyone wrote to the cache while we where waiting our turn to write the new value.
cachedData = MemoryCache.Default.Get(cacheKey, null) as T;
if (cachedData != null)
{
return cachedData;
}
//The value still did not exist so we now write it in to the cache.
CacheItemPolicy cip = new CacheItemPolicy()
{
AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(cacheTimePolicyMinutes))
};
cachedData = GetData();
MemoryCache.Default.Set(cacheKey, cachedData, cip);
return cachedData;
}
}
}
}
}
Dictionary<string, object>
এমনভাবে করা যেতে পারে যেখানে আপনি কীটি একই কী ব্যবহার করেন MemoryCache
এবং অভিধানে থাকা অবজেক্টটি কেবলমাত্র Object
আপনার লক করা একটি বেসিক । যাইহোক, যা বলা হচ্ছে, আমি আপনাকে জনা হানার উত্তরের মাধ্যমে পড়ার বিষয়টি স্মরণ করিয়ে দেব। যথাযথ প্রোফাইল না দিয়ে আপনি দুটি প্রোগ্রাম SomeHeavyAndExpensiveCalculation()
চালানোর চেয়ে লকিংয়ের সাথে আপনার প্রোগ্রামটি কমিয়ে ফেলতে পারেন এবং এর একটি ফল ফেলে দেওয়া হতে পারে।
ReaderWriterLockSlim
করবেন না ?