গণনা নিয়ে সমস্যা
MemoryCache.GetEnumerator () অধ্যায় মন্তব্য সমূহ সাবধান করে: "। একটি সম্পদ নিবিড় এবং ব্লক অপারেশন হয় MemoryCache উদাহরণস্বরূপ একটি গণনাকারী পুনরুদ্ধার করা হচ্ছে অতএব, গণনাকারী প্রকাশনা অ্যাপ্লিকেশন ব্যবহার করা উচিত।"
এখানেই getEnumerator () বাস্তবায়নের সিউডোকোডে ব্যাখ্যা করা হয়েছে:
Create a new Dictionary object (let's call it AllCache)
For Each per-processor segment in the cache (one Dictionary object per processor)
{
Lock the segment/Dictionary (using lock construct)
Iterate through the segment/Dictionary and add each name/value pair one-by-one
to the AllCache Dictionary (using references to the original MemoryCacheKey
and MemoryCacheEntry objects)
}
Create and return an enumerator on the AllCache Dictionary
যেহেতু বাস্তবায়ন একাধিক ডিকশনারি অবজেক্টগুলিতে ক্যাশে বিভক্ত হয়, তাই একজন গণককে ফেরত দেওয়ার জন্য এটি অবশ্যই সমস্ত কিছু একত্রে সংগ্রহের মধ্যে নিয়ে আসে। GetEnumerator- এ প্রতিটি কল উপরে বর্ণিত সম্পূর্ণ অনুলিপি প্রক্রিয়াটি সম্পাদন করে। নতুন তৈরি করা অভিধানটিতে মূল অভ্যন্তরীণ কী এবং মান অবজেক্টের উল্লেখ রয়েছে, সুতরাং আপনার প্রকৃত ক্যাশেড ডেটা মানগুলি সদৃশ হয় না।
ডকুমেন্টেশনে সতর্কতাটি সঠিক। GetEnumerator () এড়িয়ে চলুন - উপরের সমস্ত উত্তর যা লিনকিউ ক্যোয়ারী ব্যবহার করে including
একটি ভাল এবং আরও নমনীয় সমাধান
ক্যাশে সাফ করার একটি কার্যকর উপায় যা কেবল বিদ্যমান পরিবর্তন পর্যবেক্ষণের অবকাঠামোকে সহজভাবে গড়ে তোলে। এটি পুরো ক্যাশে বা কেবল একটি নামকৃত উপসেটটি সাফ করার জন্য নমনীয়তা সরবরাহ করে এবং উপরে আলোচিত সমস্যাগুলির মধ্যে একটিও নেই।
namespace CacheTest
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Caching;
public class SignaledChangeEventArgs : EventArgs
{
public string Name { get; private set; }
public SignaledChangeEventArgs(string name = null) { this.Name = name; }
}
public class SignaledChangeMonitor : ChangeMonitor
{
private static event EventHandler<SignaledChangeEventArgs> Signaled;
private string _name;
private string _uniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
public override string UniqueId
{
get { return _uniqueId; }
}
public SignaledChangeMonitor(string name = null)
{
_name = name;
SignaledChangeMonitor.Signaled += OnSignalRaised;
base.InitializationComplete();
}
public static void Signal(string name = null)
{
if (Signaled != null)
{
Signaled(null, new SignaledChangeEventArgs(name));
}
}
protected override void Dispose(bool disposing)
{
SignaledChangeMonitor.Signaled -= OnSignalRaised;
}
private void OnSignalRaised(object sender, SignaledChangeEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.Name) || string.Compare(e.Name, _name, true) == 0)
{
Debug.WriteLine(
_uniqueId + " notifying cache of change.", "SignaledChangeMonitor");
base.OnChanged(null);
}
}
}
public static class CacheTester
{
public static void TestCache()
{
MemoryCache cache = MemoryCache.Default;
for (int idx = 0; idx < 50; idx++)
{
cache.Add("Key" + idx.ToString(), "Value" + idx.ToString(), GetPolicy(idx));
}
SignaledChangeMonitor.Signal("NamedData");
SignaledChangeMonitor.Signal();
}
private static CacheItemPolicy GetPolicy(int idx)
{
string name = (idx % 2 == 0) ? null : "NamedData";
CacheItemPolicy cip = new CacheItemPolicy();
cip.AbsoluteExpiration = System.DateTimeOffset.UtcNow.AddHours(1);
cip.ChangeMonitors.Add(new SignaledChangeMonitor(name));
return cip;
}
}
}