Asp.net Core2.0 快取 MemoryCache 和 Redis
自從使用Asp.net Core2.0 以來,不停摸索,查閱資料,這方面的資料是真的少,因此,在前人的基礎上,摸索出了Asp.net Core2.0 快取 MemoryCache 和 Redis的用法,並實現了簡單的封裝
那麼,先給出幾個參考資料吧
關於兩種快取:https://www.cnblogs.com/yuangang/p/5800113.html
關於redis持久化:https://blog.csdn.net/u010785685/article/details/52366977
兩個nuget包,不用多說
接下來,貼出程式碼
首先在startup,我讀取了appstting.json的資料,作為redis的配置
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Application.Common; using Application.Common.CommonObject; using Application.CoreWork; using Application.DAL; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Application.web { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { Connection.MySqlConnection = Configuration.GetConnectionString("MySqlConnection"); Connection.SqlConnection = Configuration.GetConnectionString("SqlConnection"); RedisConfig.Connection = Configuration.GetSection("RedisConfig")["Connection"]; RedisConfig.DefaultDatabase =Convert.ToInt32( Configuration.GetSection("RedisConfig")["DefaultDatabase"]); RedisConfig.InstanceName = Configuration.GetSection("RedisConfig")["InstanceName"]; CommonManager.CacheObj.GetMessage<RedisCacheHelper>(); services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
再貼上配置
1 2 3 4 5 |
"RedisConfig" : {
"Connection"
:
"127.0.0.1:6379"
,
"DefaultDatabase"
: 0,
"InstanceName"
:
"Redis1"
},
|
用來放配置資訊的靜態類
using System; using System.Collections.Generic; using System.Text; namespace Application.Common { public static class RedisConfig { public static string configname { get; set; } public static string Connection { get; set; } public static int DefaultDatabase { get; set; } public static string InstanceName { get; set; } } }
然後ICacheHelper.cs,這個類是兩種快取通用的介面,讓使用更方便
using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public interface ICacheHelper { bool Exists(string key); T GetCache<T>(string key) where T : class; void SetCache(string key, object value); void SetCache(string key, object value, DateTimeOffset expiressAbsoulte);//設定絕對時間過期 void SetSlidingCache(string key, object value, TimeSpan t); //設定滑動過期, 因redis暫未找到自帶的滑動過期類的API,暫無需實現該介面 void RemoveCache(string key); void KeyMigrate(string key, EndPoint endPoint,int database,int timeountseconds); void Dispose(); void GetMssages(); void Publish(string msg); } }
然後,實現介面,首先是MemoryCacheHelper
using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public class MemoryCacheHelper : ICacheHelper { //public MemoryCacheHelper(/*MemoryCacheOptions options*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把選項直接封在幫助類裡邊 //{ // //this._cache = new MemoryCache(options); // //this._cache = new MemoryCache(new MemoryCacheOptions()); //} //public MemoryCacheHelper(MemoryCacheOptions options)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把選項直接封在幫助類裡邊 //{ // this._cache = new MemoryCache(options); //} public static IMemoryCache _cache=new MemoryCache(new MemoryCacheOptions()); /// <summary> /// 是否存在此快取 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Exists(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); object v = null; return _cache.TryGetValue<object>(key, out v); } /// <summary> /// 取得快取資料 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T GetCache<T>(string key) where T : class { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); T v = null; _cache.TryGetValue<T>(key, out v); return v; } /// <summary> /// 設定快取 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void SetCache(string key, object value) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set<object>(key, value); } /// <summary> /// 設定快取,絕對過期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationMinute">間隔分鐘</param> /// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", 30); public void SetCache(string key, object value, double expirationMinute) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); DateTime now = DateTime.Now; TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now; _cache.Set<object>(key, value, ts); } /// <summary> /// 設定快取,絕對過期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationTime">DateTimeOffset 結束時間</param> /// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", DateTimeOffset.Now.AddSeconds(30)); public void SetCache(string key, object value, DateTimeOffset expirationTime) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set<object>(key, value, expirationTime); } /// <summary> /// 設定快取,相對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="t"></param> /// CommonManager.CacheObj.SaveSlidingCache<MemoryCacheHelper>("test", "MemoryCache works!",TimeSpan.FromSeconds(30)); public void SetSlidingCache(string key,object value,TimeSpan t) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set(key, value, new MemoryCacheEntryOptions() { SlidingExpiration=t }); } /// <summary> /// 移除快取 /// </summary> /// <param name="key"></param> public void RemoveCache(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.Remove(key); } /// <summary> /// 釋放 /// </summary> public void Dispose() { if (_cache != null) _cache.Dispose(); GC.SuppressFinalize(this); } public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds) { throw new NotImplementedException(); } public void GetMssages() { throw new NotImplementedException(); } public void Publish(string msg) { throw new NotImplementedException(); } } }
然後是RedisCacheHelper
using Microsoft.Extensions.Caching.Redis; using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public class RedisCacheHelper : ICacheHelper { public RedisCacheHelper(/*RedisCacheOptions options, int database = 0*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把連線資訊直接寫在幫助類裡 { options = new RedisCacheOptions(); options.Configuration = "127.0.0.1:6379";//RedisConfig.Connection; options.InstanceName = RedisConfig.InstanceName; int database = RedisConfig.DefaultDatabase; _connection = ConnectionMultiplexer.Connect(options.Configuration); _cache = _connection.GetDatabase(database); _instanceName = options.InstanceName; _sub = _connection.GetSubscriber(); } public static RedisCacheOptions options; public static IDatabase _cache; public static ConnectionMultiplexer _connection; public static string _instanceName; public static ISubscriber _sub; /// <summary> /// 取得redis的Key名稱 /// </summary> /// <param name="key"></param> /// <returns></returns> private string GetKeyForRedis(string key) { return _instanceName + key; } /// <summary> /// 判斷當前Key是否存在資料 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Exists(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); return _cache.KeyExists(GetKeyForRedis(key)); } /// <summary> /// 取得快取資料 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T GetCache<T>(string key) where T : class { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); var value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) return default(T); return JsonConvert.DeserializeObject<T>(value); } /// <summary> /// 設定快取資料 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void SetCache(string key, object value) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value)); } /// <summary> /// 設定絕對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiressAbsoulte"></param> public void SetCache(string key, object value, DateTimeOffset expiressAbsoulte) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); TimeSpan t = expiressAbsoulte - DateTimeOffset.Now; _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), t); } /// <summary> /// 設定相對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationMinute"></param> public void SetCache(string key, object value, double expirationMinute) { if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); DateTime now = DateTime.Now; TimeSpan ts = now.AddMinutes(expirationMinute) - now; _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), ts); } /// <summary> /// /// </summary> /// <param name="key"></param> /// <param name="endPoint"></param> /// <param name="database"></param> /// <param name="timeountseconds"></param> public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.KeyMigrate(GetKeyForRedis(key), endPoint, database, timeountseconds); } /// <summary> /// 移除redis /// </summary> /// <param name="key"></param> public void RemoveCache(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.KeyDelete(GetKeyForRedis(key)); } /// <summary> /// 銷燬連線 /// </summary> public void Dispose() { if (_connection != null) _connection.Dispose(); GC.SuppressFinalize(this); } public void SetSlidingCache(string key, object value, TimeSpan t) { throw new NotImplementedException(); } public void GetMssages() { using (_connection = ConnectionMultiplexer.Connect(options.Configuration)) _sub.Subscribe("msg", (channel, message) => { string result = message; }); } public void Publish(string msg) { using (_connection=ConnectionMultiplexer.Connect(options.Configuration)) _sub.Publish("msg", msg); } } }
然後是Cache.cs,用來例項化,此處用單例模式,保證專案使用的是一個快取例項,博主吃過虧,由於redis例項過多,建構函式執行太多次,導致client連線數過大,記憶體不夠跑,速度卡慢
using System; using System.Collections.Generic; using System.Text; namespace Application.Common.CommonObject { public sealed class Cache { internal Cache() { } public static ICacheHelper cache; /// <summary> /// 判斷快取是否存在 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <returns></returns> public bool Exists<CacheType>(string key) where CacheType : ICacheHelper, new() { if (cache!=null&& typeof(CacheType).Equals(cache.GetType())) return cache.Exists(key); else { cache = new CacheType(); return cache.Exists(key); } } /// <summary> /// 獲取快取 /// </summary> /// <typeparam name="T">轉換的類</typeparam> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <returns>轉換為T型別的值</returns> public T GetCache<T,CacheType>(string key) where T:class where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) return cache.GetCache<T>(key); else { cache = new CacheType(); return cache.GetCache<T>(key); } } /// <summary> /// 儲存快取 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <param name="value">值</param> public void Save<CacheType>(string key,object value) where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetCache(key, value); else { cache = new CacheType(); cache.SetCache(key, value); } } /// <summary> /// 儲存快取並設定絕對過期時間 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <param name="value">值</param> /// <param name="expiressAbsoulte">絕對過期時間</param> public void Save<CacheType>(string key, object value, DateTimeOffset expiressAbsoulte) where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetCache(key, value, expiressAbsoulte); else { cache = new CacheType(); cache.SetCache(key, value, expiressAbsoulte); } } /// <summary> /// 儲存滑動快取 /// </summary> /// <typeparam name="CacheType">只能用memorycache,redis暫不實現</typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="t">間隔時間</param> public void SaveSlidingCache<CacheType>(string key, object value,TimeSpan t) where CacheType : MemoryCacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetSlidingCache(key, value, t); else { cache = new CacheType(); cache.SetSlidingCache(key, value, t); } } /// <summary> /// 刪除一個快取 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">要刪除的key</param> public void Delete<CacheType>(string key)where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.RemoveCache(key); else { cache = new CacheType(); cache.RemoveCache(key); } } /// <summary> /// 釋放 /// </summary> /// <typeparam name="CacheType"></typeparam> public void Dispose<CacheType>() where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.Dispose(); else { cache = new CacheType(); cache.Dispose(); } } public void GetMessage<CacheType>() where CacheType:RedisCacheHelper,new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.GetMssages(); else { cache = new CacheType(); cache.GetMssages(); } } public void Publish<CacheType>(string msg)where CacheType : RedisCacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.Publish(msg); else { cache = new CacheType(); cache.Publish(msg); } } } }
接下來,CommonManager.cs,該類主要是為了作為一個靜態類呼叫快取,由於Cache.cs並非靜態類,方便呼叫
using Application.Common.CommonObject; using System; using System.Collections.Generic; using System.Text; namespace Application.Common { public class CommonManager { private static readonly object lockobj = new object(); private static volatile Cache _cache = null; /// <summary> /// Cache /// </summary> public static Cache CacheObj { get { if (_cache == null) { lock (lockobj) { if (_cache == null) _cache = new Cache(); } } return _cache; } } } }
最後呢就是使用啦隨便建的一個控制器
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; using Application.Common; using Application.Common.CommonObject; using Application.CoreWork; using Microsoft.AspNetCore.Mvc; namespace Application.web.Controllers { public class DefaultController : BaseController { public IActionResult Index() { for (int i = 0; i < 100000; i++) { CommonManager.CacheObj.Save<RedisCacheHelper>("key" + i, "key" + i + " works!"); } return View(); } public IActionResult GetStrin(int index) { string res = "已經過期了"; if (CommonManager.CacheObj.Exists<RedisCacheHelper>("key" + index)) { res = CommonManager.CacheObj.GetCache<String, RedisCacheHelper>("key" + index); } return Json(new ExtJson { success = true, code = 1000, msg = "成功", jsonresult = res }); } public IActionResult Publish(string msg) { try { CommonManager.CacheObj.Publish<RedisCacheHelper>(msg); return Json(new ExtJson { success = true, code = 1000, msg = "成功", jsonresult = msg }); } catch { return Json(new ExtJson { success = true, code = 1000, msg = "失敗", jsonresult = msg }); } } } }
那麼,有的朋友在json處可能會報錯,自己封裝下,或者用原來的json吧
如果有不懂的地方,可以在評論中提問,有更好的改進方式,也請聯絡我,共同進步,感謝閱讀
自從使用Asp.net Core2.0 以來,不停摸索,查閱資料,這方面的資料是真的少,因此,在前人的基礎上,摸索出了Asp.net Core2.0 快取 MemoryCache 和 Redis的用法,並實現了簡單的封裝
那麼,先給出幾個參考資料吧
關於兩種快取:https://www.cnblogs.com/yuangang/p/5800113.html
關於redis持久化:https://blog.csdn.net/u010785685/article/details/52366977
兩個nuget包,不用多說
接下來,貼出程式碼
首先在startup,我讀取了appstting.json的資料,作為redis的配置
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Application.Common; using Application.Common.CommonObject; using Application.CoreWork; using Application.DAL; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Application.web { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { Connection.MySqlConnection = Configuration.GetConnectionString("MySqlConnection"); Connection.SqlConnection = Configuration.GetConnectionString("SqlConnection"); RedisConfig.Connection = Configuration.GetSection("RedisConfig")["Connection"]; RedisConfig.DefaultDatabase =Convert.ToInt32( Configuration.GetSection("RedisConfig")["DefaultDatabase"]); RedisConfig.InstanceName = Configuration.GetSection("RedisConfig")["InstanceName"]; CommonManager.CacheObj.GetMessage<RedisCacheHelper>(); services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
再貼上配置
1 2 3 4 5 |
"RedisConfig"
: {
"Connection"
:
"127.0.0.1:6379"
,
"DefaultDatabase"
: 0,
"InstanceName"
:
"Redis1"
},
|
用來放配置資訊的靜態類
using System; using System.Collections.Generic; using System.Text; namespace Application.Common { public static class RedisConfig { public static string configname { get; set; } public static string Connection { get; set; } public static int DefaultDatabase { get; set; } public static string InstanceName { get; set; } } }
然後ICacheHelper.cs,這個類是兩種快取通用的介面,讓使用更方便
using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public interface ICacheHelper { bool Exists(string key); T GetCache<T>(string key) where T : class; void SetCache(string key, object value); void SetCache(string key, object value, DateTimeOffset expiressAbsoulte);//設定絕對時間過期 void SetSlidingCache(string key, object value, TimeSpan t); //設定滑動過期, 因redis暫未找到自帶的滑動過期類的API,暫無需實現該介面 void RemoveCache(string key); void KeyMigrate(string key, EndPoint endPoint,int database,int timeountseconds); void Dispose(); void GetMssages(); void Publish(string msg); } }
然後,實現介面,首先是MemoryCacheHelper
using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public class MemoryCacheHelper : ICacheHelper { //public MemoryCacheHelper(/*MemoryCacheOptions options*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把選項直接封在幫助類裡邊 //{ // //this._cache = new MemoryCache(options); // //this._cache = new MemoryCache(new MemoryCacheOptions()); //} //public MemoryCacheHelper(MemoryCacheOptions options)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把選項直接封在幫助類裡邊 //{ // this._cache = new MemoryCache(options); //} public static IMemoryCache _cache=new MemoryCache(new MemoryCacheOptions()); /// <summary> /// 是否存在此快取 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Exists(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); object v = null; return _cache.TryGetValue<object>(key, out v); } /// <summary> /// 取得快取資料 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T GetCache<T>(string key) where T : class { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); T v = null; _cache.TryGetValue<T>(key, out v); return v; } /// <summary> /// 設定快取 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void SetCache(string key, object value) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set<object>(key, value); } /// <summary> /// 設定快取,絕對過期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationMinute">間隔分鐘</param> /// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", 30); public void SetCache(string key, object value, double expirationMinute) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); DateTime now = DateTime.Now; TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now; _cache.Set<object>(key, value, ts); } /// <summary> /// 設定快取,絕對過期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationTime">DateTimeOffset 結束時間</param> /// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", DateTimeOffset.Now.AddSeconds(30)); public void SetCache(string key, object value, DateTimeOffset expirationTime) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set<object>(key, value, expirationTime); } /// <summary> /// 設定快取,相對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="t"></param> /// CommonManager.CacheObj.SaveSlidingCache<MemoryCacheHelper>("test", "MemoryCache works!",TimeSpan.FromSeconds(30)); public void SetSlidingCache(string key,object value,TimeSpan t) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (_cache.TryGetValue(key, out v)) _cache.Remove(key); _cache.Set(key, value, new MemoryCacheEntryOptions() { SlidingExpiration=t }); } /// <summary> /// 移除快取 /// </summary> /// <param name="key"></param> public void RemoveCache(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.Remove(key); } /// <summary> /// 釋放 /// </summary> public void Dispose() { if (_cache != null) _cache.Dispose(); GC.SuppressFinalize(this); } public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds) { throw new NotImplementedException(); } public void GetMssages() { throw new NotImplementedException(); } public void Publish(string msg) { throw new NotImplementedException(); } } }
然後是RedisCacheHelper
using Microsoft.Extensions.Caching.Redis; using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Net; using System.Text; namespace Application.Common.CommonObject { public class RedisCacheHelper : ICacheHelper { public RedisCacheHelper(/*RedisCacheOptions options, int database = 0*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把連線資訊直接寫在幫助類裡 { options = new RedisCacheOptions(); options.Configuration = "127.0.0.1:6379";//RedisConfig.Connection; options.InstanceName = RedisConfig.InstanceName; int database = RedisConfig.DefaultDatabase; _connection = ConnectionMultiplexer.Connect(options.Configuration); _cache = _connection.GetDatabase(database); _instanceName = options.InstanceName; _sub = _connection.GetSubscriber(); } public static RedisCacheOptions options; public static IDatabase _cache; public static ConnectionMultiplexer _connection; public static string _instanceName; public static ISubscriber _sub; /// <summary> /// 取得redis的Key名稱 /// </summary> /// <param name="key"></param> /// <returns></returns> private string GetKeyForRedis(string key) { return _instanceName + key; } /// <summary> /// 判斷當前Key是否存在資料 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Exists(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); return _cache.KeyExists(GetKeyForRedis(key)); } /// <summary> /// 取得快取資料 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T GetCache<T>(string key) where T : class { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); var value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) return default(T); return JsonConvert.DeserializeObject<T>(value); } /// <summary> /// 設定快取資料 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void SetCache(string key, object value) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value)); } /// <summary> /// 設定絕對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiressAbsoulte"></param> public void SetCache(string key, object value, DateTimeOffset expiressAbsoulte) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); TimeSpan t = expiressAbsoulte - DateTimeOffset.Now; _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), t); } /// <summary> /// 設定相對過期時間 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationMinute"></param> public void SetCache(string key, object value, double expirationMinute) { if (Exists(GetKeyForRedis(key))) RemoveCache(GetKeyForRedis(key)); DateTime now = DateTime.Now; TimeSpan ts = now.AddMinutes(expirationMinute) - now; _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), ts); } /// <summary> /// /// </summary> /// <param name="key"></param> /// <param name="endPoint"></param> /// <param name="database"></param> /// <param name="timeountseconds"></param> public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.KeyMigrate(GetKeyForRedis(key), endPoint, database, timeountseconds); } /// <summary> /// 移除redis /// </summary> /// <param name="key"></param> public void RemoveCache(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); _cache.KeyDelete(GetKeyForRedis(key)); } /// <summary> /// 銷燬連線 /// </summary> public void Dispose() { if (_connection != null) _connection.Dispose(); GC.SuppressFinalize(this); } public void SetSlidingCache(string key, object value, TimeSpan t) { throw new NotImplementedException(); } public void GetMssages() { using (_connection = ConnectionMultiplexer.Connect(options.Configuration)) _sub.Subscribe("msg", (channel, message) => { string result = message; }); } public void Publish(string msg) { using (_connection=ConnectionMultiplexer.Connect(options.Configuration)) _sub.Publish("msg", msg); } } }
然後是Cache.cs,用來例項化,此處用單例模式,保證專案使用的是一個快取例項,博主吃過虧,由於redis例項過多,建構函式執行太多次,導致client連線數過大,記憶體不夠跑,速度卡慢
using System; using System.Collections.Generic; using System.Text; namespace Application.Common.CommonObject { public sealed class Cache { internal Cache() { } public static ICacheHelper cache; /// <summary> /// 判斷快取是否存在 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <returns></returns> public bool Exists<CacheType>(string key) where CacheType : ICacheHelper, new() { if (cache!=null&& typeof(CacheType).Equals(cache.GetType())) return cache.Exists(key); else { cache = new CacheType(); return cache.Exists(key); } } /// <summary> /// 獲取快取 /// </summary> /// <typeparam name="T">轉換的類</typeparam> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <returns>轉換為T型別的值</returns> public T GetCache<T,CacheType>(string key) where T:class where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) return cache.GetCache<T>(key); else { cache = new CacheType(); return cache.GetCache<T>(key); } } /// <summary> /// 儲存快取 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <param name="value">值</param> public void Save<CacheType>(string key,object value) where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetCache(key, value); else { cache = new CacheType(); cache.SetCache(key, value); } } /// <summary> /// 儲存快取並設定絕對過期時間 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">鍵名</param> /// <param name="value">值</param> /// <param name="expiressAbsoulte">絕對過期時間</param> public void Save<CacheType>(string key, object value, DateTimeOffset expiressAbsoulte) where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetCache(key, value, expiressAbsoulte); else { cache = new CacheType(); cache.SetCache(key, value, expiressAbsoulte); } } /// <summary> /// 儲存滑動快取 /// </summary> /// <typeparam name="CacheType">只能用memorycache,redis暫不實現</typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <param name="t">間隔時間</param> public void SaveSlidingCache<CacheType>(string key, object value,TimeSpan t) where CacheType : MemoryCacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.SetSlidingCache(key, value, t); else { cache = new CacheType(); cache.SetSlidingCache(key, value, t); } } /// <summary> /// 刪除一個快取 /// </summary> /// <typeparam name="CacheType">快取型別</typeparam> /// <param name="key">要刪除的key</param> public void Delete<CacheType>(string key)where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.RemoveCache(key); else { cache = new CacheType(); cache.RemoveCache(key); } } /// <summary> /// 釋放 /// </summary> /// <typeparam name="CacheType"></typeparam> public void Dispose<CacheType>() where CacheType : ICacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.Dispose(); else { cache = new CacheType(); cache.Dispose(); } } public void GetMessage<CacheType>() where CacheType:RedisCacheHelper,new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.GetMssages(); else { cache = new CacheType(); cache.GetMssages(); } } public void Publish<CacheType>(string msg)where CacheType : RedisCacheHelper, new() { if (cache != null && typeof(CacheType).Equals(cache.GetType())) cache.Publish(msg); else { cache = new CacheType(); cache.Publish(msg); } } } }
接下來,CommonManager.cs,該類主要是為了作為一個靜態類呼叫快取,由於Cache.cs並非靜態類,方便呼叫
相關推薦
Asp.net Core2.0 快取 MemoryCache 和 Redis
自從使用Asp.net Core2.0 以來,不停摸索,查閱資料,這方面的資料是真的少,因此,在前人的基礎上,摸索出了Asp.net Core2.0 快取 MemoryCache 和 Redis的用法,並實現了簡單的封裝 那麼,先給出幾個參考
Asp.net Core 快取 MemoryCache 和 Redis
https://blog.csdn.net/warrior21st/article/details/62884629 快取介面 ICacheService 快取也好,資料庫也好,我們就是進行CRUD操作,介面沒什麼好解釋的,註釋我寫的很明白,這裡就
【無私分享:ASP.NET CORE 專案實戰(第十一章)】Asp.net Core 快取 MemoryCache 和 Redis
1 /// <summary> 2 /// 修改快取 3 /// </summary> 4 /// <param name="key">快取Key</param> 5 ///
ASP.NET 2.0 快取和過期、連線池
問:使用 .js 和級聯樣式表 (CSS) include 時是否有什麼技巧,以便對它們進行快取,而不必在每次發出請求時都進行提取?答:為了實現這種型別的快取,您可以使用 IIS 管理單元中的 HTTP 標頭屬性表,通過選中“啟用內容過期”複選框來啟用內容過期。這樣會使用 E
WebApi遷移ASP.NET Core2.0
content .config true 進入 服務 設置 網關 系統 win WebApi遷移ASP.NET Core2.0 一步一步帶你做WebApi遷移ASP.NET Core2.0 隨著ASP.NET Core 2.0發布之後,原先運行在Windows II
Asp.NET Core2.0 項目實戰入門視頻課程_完整版
第5章 frame 封裝 今天 使用 結束 技巧 標題 技術分享 END OR START? 看到這個標題,你開不開心,激不激動呢? 沒錯,.net core的入門課程已經完畢了。52ABP.School項目從11月19日,第一章視頻的試錄制,到今天完整版出爐,離不開各位的
asp.net core1.x/asp.net core2.0中如何加載多個配置文件
加載 自己 團隊 多配置文件 做的 ted 文章 pos 簡單 寫這篇文章,來簡單的談一下,asp.net core中,如何加載多配置文件,如有錯誤請斧正。 在1.x的時候,我們是自己配置 WebHostBuilder而在2.0的時候,ef core團隊,將配置寫到了
用VSCode開發一個asp.net core2.0+angular5項目(5): Angular5+asp.net core 2.0 web api文件上傳
owb bus sed loaded runt ace created one 做了 第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.
將asp.net core2.0專案部署在IIS上執行
與ASP.NET時代不同,ASP.NET Core不再是由IIS工作程序(w3wp.exe)託管,而是獨立執行的。它獨立執行在控制檯應用程式中,並通過dotnet執行時命令呼叫。它並沒有被載入到IIS工作程序中,但是IIS卻載入了名為AspNetCoreModule的
3、ASP.Net Core2.0值Filter
Asp.Net Core的filter總共有5種,它們分別是Authorization Filter(授權過濾器)、Resource Filter(資源過濾器),Action Filter、Exception Filter(異常過濾器)和Result Filt
【翻譯】asp.net core2.0中的token認證
原文地址:https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide token認證在最近幾年正在成為一個流行的主題,特別是隨著移動應用和js應用不斷的獲得關注。像OAuth 2.0和Op
在阿里雲Windows Server 上部署ASP .NET CORE2.0專案
近期使用ASP.NET Core2.0對部落格進行了重寫,在部署到伺服器時遇到了一些問題,來記錄一下留用。 配置環境 安裝 .Net Framework3.5 在IIS管理器上直接開啟,這裡總是失敗,上網上找了找,發現了可以使用命令列安裝,開啟Pow
core學習歷程五 從壹開始前後端分離【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面程式設計淺解析:簡單日誌記錄 + 服務切面快取 從壹開始前後端分離【 .NET Core2.0 +Vue2.0 】框架之十一 || AOP自定義篩選,Redis入門 11.1
繼續學習 “老張的哲學”博主的系列教程,感謝大神們的無私分享 從壹開始前後端分離【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面程式設計淺解析:簡單日誌記錄 + 服務切面快取 說是朦朧,,emmm,對我來說是迷糊哈。上半段正常,下半段有點難理解,操作是沒問題。多看幾遍再消
基於Asp.net Core 3.1實現的Redis及MemoryCache快取助手CacheHelper
這幾天在面試,這個關於Redis快取的部落格一直沒空寫,今天總算有點時間了。 從很久很久之前,我就一直想學Redis了,反正看到各大招聘網上都要求Redis,不學就太落後了。 一開始我是按微軟官網文件那樣配置的,然後發現這也太簡單了,不止配置簡單,連使用都這麼簡單,簡單得有點過分。如下圖所示,它
Asp.Net Core 2.0 項目實戰(2)NCMVC一個基於Net Core2.0搭建的角色權限管理開發框架
ML 用戶 解密 https redis json uil AI 不足 本文目錄 1. 摘要 2. 框架介紹 3. 權限管理之多一點說明 4. 總結 1. 摘要 NCMVC角色權限管理框架是由最近練習Net Core時抽時間整理的
在asp.net core2.1中新增中介軟體以擴充套件Swashbuckle.AspNetCore3.0支援簡單的文件訪問許可權控制
Swashbuckle.AspNetCore3.0 介紹 一個使用 ASP.NET Core 構建的 API 的 Swagger 工具。直接從您的路由,控制器和模型生成漂亮的 API 文件,包括用於探索和測試操作的 UI。 專案主頁:https://github.com/domaindrivendev/Sw
從壹開始前後端分離【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面程式設計淺解析:簡單日誌記錄 + 服務切面快取
今天的講解就到了這裡了,通過這兩個小栗子,大家應該能對面向切面程式設計有一些朦朧的感覺了吧
從壹開始前後端分離【 .NET Core2.0 +Vue2.0 】框架之十一 || AOP自定義篩選,Redis入門 11.1
大神留步 先說下一個窩心的問題,求大神幫忙,如何在AOP中去使用泛型,有償幫助,這裡謝謝,文末有詳細問題說明,可以留言或者私信都可以。 當然我也會一直思考,大家持續關注本帖,如果我想到好辦法,會及時更新,並通知大家。 程式碼已上傳Github+Gitee,文末有地址 傳統的快取是在Co
解決 web伺服器部署常見問題,server application unavailable 和 程式無法連線資料庫 的問題(asp.net 2.0 + oracle9i + winXP)
部署時出現以下錯誤: server application unavailable the web application you are attempting to access on this web server is currently unavailable. pl
asp.net ajax 和 asp.net 2.0中的fileupload合力打造無重新整理檔案上傳控制元件
{20 bool fileOK =false;21 //獲取根檔案絕對路徑22string path = Server.MapPath("~/UpLoad/");23 //如上傳了檔案,就判斷檔案格式24 FileUpload FU = FileUplo