[爬蟲學習筆記]MemoryCache緩存的用法學習


      在完成了DNS解析模塊之后,我意識到了DNS緩存機制也很有必要。在Redis,Memcache,和.Net自帶的Cache之間,考慮到部署問題,最終選擇了后者,之前在學習Web及開發的過程中用過System.Web.Caching.Cache這個類庫,但是這次的爬蟲程序我打算部署為桌面軟件,所以選用了System.Runtime.Caching.MemoryCache(后期如有必要也會加入System.Web.Caching.Cache來適配Web端程序)。

      MemoryCache的使用網上介紹的不多,不過這個是.NET4.0新引入的緩存對象,估計主要是替換原來企業庫的緩存模塊,使得.NET的緩存可以無處不在,而不用基於特定的Windows版本上使用。

      出於方便考慮,我們將不再實例化新的MemoryCache對象,只對MemoryCache的默認示例Memory.Default進行增刪查操作。

基礎篇

增加:

image

增加緩存需要提供兩個參數,CacheItem類表示緩存中的單個緩存項,

構造函數:
CacheItem(String, Object, String)            用緩存項的指定鍵、值和區域初始化新的 CacheItem 實例。

三個參數分別為:鍵、值和區域。

CacheItemPolicy類則表示緩存項的過期信息,只含有默認的構造函數。

增加一條緩存:

var item = new CacheItem("習大大", "兩學一做");
var policy = new CacheItemPolicy();
policy.SlidingExpiration = new TimeSpan(500);
//插入一條key為"習大大",value為"兩學一做",500毫秒后自動銷毀的緩存
MemoryCache.Default.Add(item, policy);
//重新設置policy的過期時間為當前時間+十分鍾
policy.AbsoluteExpiration = DateTimeOffset.Now + TimeSpan.FromMinutes(10);
//注意,如果要使用Sliding時間,則Absolute必須為DateTimeOffset.MaxValue,反之,則Sliding必須為TimeSpan.Zero
policy.SlidingExpiration = TimeSpan.Zero;
//重新插入,覆蓋前一條數據
MemoryCache.Default.Add(item, policy);
注意,如果要使用Sliding時間,則Absolute必須為DateTimeOffset.MaxValue,反之,則Sliding必須為TimeSpan.Zero 

查詢:

緩存對象類似於字典集,查詢可以直接采用memoryCache[key]來進行,例如我們查詢一下前面插入的那條數據:

var idea = MemoryCache.Default["習大大"];

移除:

image

參數
key:要移除的緩存項的唯一標識符。
regionName:緩存中的一個添加了緩存項的命名區域。不要為該參數傳遞值。默認情況下,此參數為 null,因為 MemoryCache 類未實現區域。
返回值
Type: System.Object  如果在緩存中找到該項,則為已移除的緩存項;否則為 null。

刪除前面加入的那一項:

MemoryCache.Default.Remove("習大大");

進階篇

明白了基本的用法之后,我們就可以對它做進一步的封裝,使之使用起來更為便捷:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;

namespace Crawler.Common
{
    /// <summary>
    /// 基於MemoryCache的緩存輔助類
    /// </summary>
    public static class MemoryCacheHelper
    {
        private static readonly object _locker = new object();

        public static bool Contains(string key)
        {
            return MemoryCache.Default.Contains(key);
        }


        /// <summary>
        /// 獲取Catch元素
        /// </summary>
        /// <typeparam name="T">所獲取的元素的類型</typeparam>
        /// <param name="key">元素的鍵</param>
        /// <returns>特定的元素值</returns>
        public static T Get<T>(string key)
        {
            if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("不合法的key!");
            if (!MemoryCache.Default.Contains(key))
                throw new ArgumentException("獲取失敗,不存在該key!");
            if (!(MemoryCache.Default[key] is T))
                throw new ArgumentException("未找到所需類型數據!");
            return (T)MemoryCache.Default[key];
        }

        /// <summary>
        /// 添加Catch元素
        /// </summary>
        /// <param name="key">元素的鍵</param>
        /// <param name="value">元素的值</param>
        /// <param name="slidingExpiration">元素過期時間(時間間隔)</param>
        /// <param name="absoluteExpiration">元素過期時間(絕對時間)</param>
        /// <returns></returns>
        public static bool Add(string key, object value, TimeSpan? slidingExpiration = null, DateTime? absoluteExpiration = null)
        {
            var item = new CacheItem(key, value);
            var policy = CreatePolicy(slidingExpiration, absoluteExpiration);
            lock (_locker)
                return MemoryCache.Default.Add(item, policy);
        }

        /// <summary>
        /// 移出Cache元素
        /// </summary>
        /// <typeparam name="T">待移出元素的類型</typeparam>
        /// <param name="key">待移除元素的鍵</param>
        /// <returns>已經移出的元素</returns>
        public static T Remove<T>(string key)
        {
            if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("不合法的key!");
            if (!MemoryCache.Default.Contains(key))
                throw new ArgumentException("獲取失敗,不存在該key!");
            var value = MemoryCache.Default.Get(key);
            if (!(value is T))
                throw new ArgumentException("未找到所需類型數據!");
            return (T)MemoryCache.Default.Remove(key);
        }

        /// <summary>
        /// 移出多條緩存數據,默認為所有緩存
        /// </summary>
        /// <typeparam name="T">待移出的緩存類型</typeparam>
        /// <param name="keyList"></param>
        /// <returns></returns>
        public static List<T> RemoveAll<T>(IEnumerable<string> keyList = null)
        {
            if (keyList != null)
                return (from key in keyList
                        where MemoryCache.Default.Contains(key)
                        where MemoryCache.Default.Get(key) is T
                        select (T)MemoryCache.Default.Remove(key)).ToList();
            while (MemoryCache.Default.GetCount() > 0)
                MemoryCache.Default.Remove(MemoryCache.Default.ElementAt(0).Key);
            return new List<T>();
        }

        /// <summary>
        /// 設置過期信息
        /// </summary>
        /// <param name="slidingExpiration"></param>
        /// <param name="absoluteExpiration"></param>
        /// <returns></returns>
        private static CacheItemPolicy CreatePolicy(TimeSpan? slidingExpiration, DateTime? absoluteExpiration)
        {
            var policy = new CacheItemPolicy();

            if (absoluteExpiration.HasValue)
            {
                policy.AbsoluteExpiration = absoluteExpiration.Value;
            }
            else if (slidingExpiration.HasValue)
            {
                policy.SlidingExpiration = slidingExpiration.Value;
            }

            policy.Priority = CacheItemPriority.Default;

            return policy;
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM