[c#] System.Runtime.Caching.MemoryCache vs HttpRuntime.Cache - هل هناك أي اختلافات؟



Answers

هنا مقال جون ديفيس. للحفاظ على قابلية القراءة ، أقصص قسم EntLib القديم ، والمقدمة بالإضافة إلى الاستنتاج.

ذاكرة التخزين المؤقت ASP.NET

ASP.NET ، أو التجميع System.Web.dll ، لديه آلية التخزين المؤقت. لم يُقصد استخدامه أبدًا خارج سياق الويب ، ولكن يمكن استخدامه خارج الويب ، كما أنه يؤدي جميع سلوكيات انتهاء الصلاحية المذكورة أعلاه في تصنيف قابل للضبط.

بعد البحث في Google ، يبدو أن عددًا قليلاً من الأشخاص الذين ناقشوا وظيفة التخزين المؤقت المضمنة في .NET قد لجأوا إلى استخدام ذاكرة التخزين المؤقت ASP.NET في مشاريعهم غير التابعة للويب. هذا لم يعد نظام التخزين المؤقت المضمّن الأكثر المتوفرة والأكثر دعمًا في .NET؛ .NET 4 يحتوي على ObjectCache التي سوف تحصل في وقت لاحق. لطالما كانت Microsoft تصر على أن ذاكرة التخزين المؤقت لـ ASP.NET غير مخصصة للاستخدام خارج الويب. لكن العديد من الأشخاص لا يزالون عالقين في .NET 2.0 و .NET 3.5 ، ويحتاجون إلى شيء يمكن العمل معه ، وهذا يحدث للعمل مع العديد من الأشخاص ، على الرغم من أن MSDN تقول بوضوح:

ملاحظة: فئة Cache غير مخصصة للاستخدام خارج تطبيقات ASP.NET. تم تصميمه واختباره للاستخدام في ASP.NET لتوفير التخزين المؤقت لتطبيقات الويب. في أنواع أخرى من التطبيقات ، مثل تطبيقات وحدة التحكم أو تطبيقات Windows Forms ، قد لا يعمل التخزين المؤقت لـ ASP.NET بشكل صحيح.

فئة ذاكرة التخزين المؤقت ASP.NET هي System.Web.Caching.Cache في System.Web.dll. ومع ذلك ، لا يمكنك ببساطة تحديث كائن ذاكرة التخزين المؤقت. يجب الحصول عليها من System.Web.HttpRuntime.Cache.

Cache cache = System.Web.HttpRuntime.Cache;

يتم توثيق العمل مع ذاكرة التخزين المؤقت ASP.NET على MSDN here .

الايجابيات:

  1. انها بنيت في .
  2. على الرغم من تركيب .NET 1.0 ، إلا أنه سهل الاستخدام إلى حد ما.
  3. عند استخدامها في سياق الويب ، يتم اختبارها جيدًا . خارج سياقات الويب ، وفقًا لعمليات بحث Google ، لا يُعرف عادةً أنها تسبب مشكلات ، على الرغم من أن Microsoft توصي بها ، طالما أنك تستخدم .NET 2.0 أو أحدث.
  4. يمكن أن يتم إعلامك عن طريق المفوض عند إزالة أي عنصر ، وهو أمر ضروري إذا احتجت إلى إبقائه على قيد الحياة ولم تتمكن من تحديد أولوية العنصر مسبقًا.
  5. تتمتع العناصر الفردية بمرونة أي من (أ) ، (ب) ، أو (ج) طرق انتهاء الصلاحية والإزالة في قائمة طرق الإزالة في الجزء العلوي من هذه المقالة. يمكنك أيضًا ربط سلوك انتهاء الصلاحية بوجود ملف فعلي.

سلبيات:

  1. ليس فقط هو ثابت ، هناك واحد فقط . لا يمكنك إنشاء نوع خاص بك بمثيل ثابت خاص به لذاكرة التخزين المؤقت. لا يمكنك سوى الحصول على مجموعة واحدة للتطبيق بالكامل ، لفترة. يمكنك التفاف الدلو مع الأغلفة الخاصة بك التي تقوم بأشياء مثل البادئات السابقة للحقن في المفاتيح وإزالة هذه البادئات عند سحب أزواج المفاتيح / القيمة للخارج. ولكن لا يزال هناك دلو واحد فقط. يتم جمع كل شيء معًا. قد يكون هذا مصدر إزعاج حقيقي ، على سبيل المثال ، إذا كان لديك خدمة تحتاج إلى تخزين ثلاثة أو أربعة أنواع مختلفة من البيانات بشكل منفصل. هذا لا ينبغي أن يكون مشكلة كبيرة للمشاريع البسيطة المثيرة للشفقة. ولكن إذا كان للمشروع أي درجة كبيرة من التعقيد بسبب متطلباته ، فإن ذاكرة التخزين المؤقت ASP.NET لن تكون كافية عادة.
  2. يمكن أن تختفي العناصر ، طوعا أو كرها . هناك الكثير من الأشخاص ليسوا على دراية بهذا الأمر - لم أكن ، حتى قمت بتحديث معرفتي حول تنفيذ ذاكرة التخزين المؤقت هذه. بشكل افتراضي ، تم تصميم ذاكرة التخزين المؤقت ASP.NET لتدمير العناصر عندما "تشعر" مثلها. بشكل أكثر تحديدًا ، راجع (ج) في التعريف الخاص بي لجدول التخزين المؤقت في الجزء العلوي من هذه المقالة. إذا كان مؤشر ترابط آخر في نفس العملية يعمل على شيء مختلف تمامًا ، ويتم تفريغ العناصر ذات الأولوية العالية في ذاكرة التخزين المؤقت ، فعندئذ تقرر NET أنه يحتاج إلى بعض الذاكرة ، سيبدأ في إتلاف بعض العناصر في ذاكرة التخزين المؤقت وفقًا لـ أولوياتهم ، أولويات أقل أولاً. تستخدم جميع الأمثلة الموثقة هنا لإضافة عناصر ذاكرة التخزين المؤقت الأفضلية الافتراضية ، بدلاً من قيمة الأولوية NotRemovable التي تحافظ على إزالتها لأغراض تخليص الذاكرة ، ولكنها ستستمر في إزالتها وفقًا لسياسة انتهاء الصلاحية. يمكن أن تكون عملية التجشؤ CacheItemPriority.NotRemovable في دعوات ذاكرة التخزين المؤقت بطيئة ، وإلا فالغلاف ضروري.
  3. يجب أن يكون المفتاح عبارة عن سلسلة. على سبيل المثال ، إذا كنت تقوم بالتخزين المؤقت لسجلات البيانات حيث يتم وضع السجلات على أساس طويل أو عدد صحيح ، فيجب عليك تحويل المفتاح إلى سلسلة أولاً.
  4. بناء الجملة هو تالفة . انها بناء جملة NET 1.0 ، أقبح من ArrayList أو Hashtable. لا توجد أدوية جنيسة هنا ، لا واجهة IDictionary <>. ليس له طريقة () (Contains) ، ولا توجد مجموعة مفاتيح (Keys) ، ولا توجد أحداث قياسية. يحتوي فقط على أسلوب Get () بالإضافة إلى مفهرس يقوم بنفس الشيء كـ Get () ، ويعود إلى null إذا لم يكن هناك تطابق ، بالإضافة إلى Add () ، و Insert () (redundant؟) ، و Remove () ، و GetEnumerator () .
  5. يتجاهل مبدأ DRY الخاص بإعداد سلوكيات الإزالة / الإزالة الافتراضية الخاصة بك حتى يمكنك نسيانها. يجب عليك إخبار ذاكرة التخزين المؤقت بوضوح كيف تريد أن تنتهي صلاحية العنصر الذي تضيفه أو تتم إزالته في كل مرة تضيف فيها عنصرًا.
  6. لا توجد طريقة للوصول إلى تفاصيل التخزين المؤقت لعنصر مخبأة مثل طابع الوقت الذي تمت إضافته فيه. ذهب التغليف قليلاً إلى حد ما هنا ، مما جعل من الصعب استخدام ذاكرة التخزين المؤقت عندما تكون في الكود الذي تحاول تحديد ما إذا كان يجب إبطال عنصر مخبأ مقابل آلية تخزين مؤقت أخرى (أي تجميع جلسة) أم لا.
  7. لا يتم عرض أحداث الإزالة باعتبارها أحداثًا ويجب تتبعها في وقت الإضافة.
  8. وإذا لم أقلها بما فيه الكفاية ، فإن Cache خارج الويب. وإذا كنت ملعونًا بـ .NET 1.1 ، فمن المفترض ألا تستخدمه مع أي ثقة في الثبات على الإطلاق خارج الويب حتى لا تهتم.

.NET 4.0's ObjectCache / MemoryCache

قامت Microsoft أخيراً بتطبيق فئة ObjectCache مجردة في أحدث إصدار من .NET Framework ، وتطبيق MemoryCache يرث ويطبق ObjectCache لأغراض الذاكرة في إعداد غير ويب.

System.Runtime.Caching.ObjectCache في التجميع System.Runtime.Caching.dll. إنها فئة مجردة التي تعلن بشكل أساسي نفس واجهات نمط .NET 1.0 التي تم العثور عليها في ذاكرة التخزين المؤقت ASP.NET. System.Runtime.Caching.MemoryCache هو تطبيق الذاكرة في ObjectCache وهو مشابه جدًا لذاكرة التخزين المؤقت ASP.NET ، مع بعض التغييرات.

لإضافة عنصر مع انتهاء صلاحية منزلق ، ستبدو شفرتك كالتالي:

var config = new NameValueCollection();  
var cache = new MemoryCache("myMemCache", config);  
cache.Add(new CacheItem("a", "b"),  
    new CacheItemPolicy  
    {  
        Priority = CacheItemPriority.NotRemovable,  
        SlidingExpiration=TimeSpan.FromMinutes(30)  
    }); 

الايجابيات:

  1. إنها مدمجة ، وهي مدعومة الآن وموصى بها من قبل Microsoft خارج الويب.
  2. بخلاف ذاكرة التخزين المؤقت ASP.NET ، يمكنك إنشاء مثيل كائن MemoryCache.

    ملاحظة: لا يجب أن تكون ثابتة ، ولكن يجب أن تكون كذلك - وهذا هو توصية شركة Microsoft (انظر تحذير أصفر) .

  3. تم إجراء بعض التحسينات الطفيفة مقابل واجهة ASP.NET التخزين المؤقت ، مثل القدرة على الاشتراك في أحداث إزالة دون بالضرورة أن يكون هناك عند إضافة العناصر ، تمت إزالة Insert () المكررة ، يمكن إضافة العناصر مع CacheItem كائن باستخدام مُهيئ يحدد استراتيجية التخزين المؤقت ، وتمت إضافة Contains ().

سلبيات:

  1. لا يزال لا يعزز تماما الجافة. من مقدار صغير من الخبرة ، مازلت لا يمكن تعيين انتهاء TimeFan الانزلاق مرة واحدة ونسيانها. وبصراحة ، على الرغم من أن السياسة في البند - إضافة عينة أعلاه هو أكثر قابلية للقراءة ، فإنه يتطلب الإسهاب الرهيبة.
  2. لا يزال غير مرتبك يتطلب سلسلة كمفتاح. لذلك لا يمكنك تخزينها لمدة طويلة أو كثافة int إذا كنت تقوم بالتخزين المؤقت لسجلات البيانات ، ما لم يتم تحويلها إلى سلسلة.

DIY: بناء واحدة نفسك

من السهل جدًا إنشاء قاموس تخزين مؤقت يؤدي إلى انتهاء الصلاحية بشكل صريح أو انزلاق. (يصبح الأمر أصعب بكثير إذا كنت تريد إزالة العناصر تلقائيًا لأغراض مسح الذاكرة.) وإليك كل ما عليك القيام به:

  1. إنشاء فئة حاوية قيمة تسمى شيئًا مثل Expiring أو Expirable التي قد تحتوي على قيمة للنوع T ، وهي خاصية TimeStamp من النوع DateTime لتخزينها عند إضافة القيمة إلى ذاكرة التخزين المؤقت ، و TimeSpan التي تشير إلى مدى بعيدًا عن الطابع الزمني يجب أن تنتهي صلاحية البند. بالنسبة إلى انتهاء الصلاحية الصريح ، يمكنك فقط عرض أداة ضبط الخاصية التي تُعين TimeSpan على تاريخ طرحها بالطابع الزمني.
  2. إنشاء فئة ، دعنا نسميها ExpirableItemsDictionary ، الذي ينفذ IDictionary. أفضل أن أجعلها فئة عامة مع تعريفها من قبل المستهلك.
  3. في الفئة التي تم إنشاؤها في # 2 ، أضف قاموس> كخاصية واسمه InnerDictionary.
  4. التنفيذ إذا كان IDictionary في الفئة التي تم إنشاؤها في # 2 يجب أن يستخدم InnerDictionary لتخزين العناصر المخزنة مؤقتًا. سيخفي التغليف تفاصيل طريقة التخزين المؤقت عبر مثيلات من النوع الذي تم إنشاؤه في # 1 أعلاه.
  5. تأكد من أن المفهرس (هذا []) و ContainsKey () ، إلخ ، حريصون على مسح العناصر منتهية الصلاحية وإزالة العناصر منتهية الصلاحية قبل عرض قيمة. قم بإرجاع null في getters إذا تمت إزالة العنصر.
  6. استخدام تأمين مؤشر الترابط على جميع getters ، setters ، ContainsKey () ، وخاصة عند مسح العناصر منتهية الصلاحية.
  7. ارفع حدثًا عندما تتم إزالة عنصر بسبب انتهاء الصلاحية.
  8. إضافة مثيل System.Threading.Timer وتثبيته أثناء التهيئة لإزالة العناصر منتهية الصلاحية كل 15 ثانية. هذا هو نفس سلوك ذاكرة التخزين المؤقت ASP.NET.
  9. قد ترغب في إضافة روتين AddOrUpdate () الذي يدفع انتهاء صلاحية الانزلاق باستبدال الطابع الزمني على حاوية العنصر (انتهاء الصلاحية) إذا كان موجودًا بالفعل.

يجب أن تدعم Microsoft تصميماتها الأصلية نظرًا لأن قاعدة المستخدمين لديها قامت بتكوين تبعية عليها ، ولكن هذا لا يعني أنها تصميمات جيدة.

الايجابيات:

  1. لديك السيطرة الكاملة على التنفيذ.
  2. يمكن أن تعزز DRY عن طريق إعداد سلوكيات التخزين المؤقت الافتراضية ومن ثم إسقاط أزواج المفاتيح / القيم دون الإعلان عن تفاصيل التخزين المؤقت في كل مرة تقوم فيها بإضافة عنصر.
  3. يمكن تنفيذ واجهات حديثة ، وهي IDictionary<K,T> . هذا يجعل الأمر أسهل للاستهلاك كما واجهة أكثر قابلية للتنبؤ كواجهة القاموس ، بالإضافة إلى أنه يجعل الوصول إليها أكثر للمساعدين وطرق الملحق التي تعمل مع IDACK <>.
  4. يمكن أن تكون تفاصيل التخزين المؤقت غير قابلة للكسر ، مثل الكشف عن InnerDictionary الخاص بك عن طريق خاصية القراءة فقط العامة ، مما يسمح لك بكتابة اختبارات وحدة صريحة ضد استراتيجية التخزين المؤقت الخاصة بك بالإضافة إلى توسيع تطبيق التخزين المؤقت الأساسي الخاص بك مع استراتيجيات التخزين المؤقت الإضافية التي تبني عليها.
  5. على الرغم من أنه ليس بالضرورة واجهة مألوفة لأولئك الذين جعلوا أنفسهم مرتاحين مع بناء جملة نمط .NET 1.0 من ذاكرة التخزين المؤقت ASP.NET أو Caching Application Block ، يمكنك تعريف الواجهة لتبدو وكأنها تريد أن تبدو.
  6. يمكن استخدام أي نوع للمفاتيح. هذا هو أحد أسباب إنشاء الأدوية الجنسية. لا ينبغي أن يكون كل شيء مرتبطا بسلسلة.

سلبيات:

  1. لا يتم اختراعها من قبل Microsoft أو تصديقها ، لذا لن يكون لها نفس مستوى ضمان الجودة.
  2. بافتراض تنفيذ الإرشادات الموضحة أعلاه فقط ، لا تقوم بإزالة العناصر "clearly" من أجل مسح الذاكرة على أساس الأولوية (وهي وظيفة الأداة المساعدة للزاوية في ذاكرة التخزين المؤقت على أي حال .. اشتر RAM حيث ستستخدم ذاكرة التخزين المؤقت وذاكرة الوصول العشوائي رخيصة).

من بين كل أربعة من هذه الخيارات ، هذا هو تفضيل. لقد نفذت هذا الحل التخزين المؤقت الأساسي. حتى الآن ، يبدو أنها تعمل بشكل مثالي ، لا توجد أخطاء معروفة (يرجى الاتصال بي مع التعليقات أدناه أو في jon-at-jondavis إذا كان هناك !!) ، وأعتزم استخدامها في جميع المشاريع الجانبية الصغيرة التي تحتاج إليها التخزين المؤقت الأساسي. ها هو:

رابط جيثب: https://github.com/kroimon/ExpirableItemDictionary

رابط قديم: ExpirableItemDictionary.zip

جدير بالذكر: AppFabric، NoSQL، Et Al

لاحظ أن عنوان مقال المدونة هذا يشير إلى "التخزين المؤقت البسيط" ، وليس "التخزين المؤقت للخدمة الشاقة". إذا كنت ترغب في الدخول في المهام الشاقة ، فيجب أن تبحث عن حلول مخصصة.

Question

أنا أتساءل عما إذا كان هناك أي اختلافات بين MemoryCache و HttpRuntime.Cache ، أي واحد هو المفضل في مشاريع ASP.NET MVC؟

بقدر ما أفهم ، وكلاهما آمن الصفحات ، API من أول نظر أكثر أو أقل من نفسه ، فهل هناك أي فرق عند استخدام أي؟






Links