從 ServiceStack.Redis V4 折騰到V3種種....,以前聽說過 StackExchange。終於下定決心換!!!網上查到一個 StackExchangeHelper.cs 具體地址忘了。
發現了一個問題:不同項目不同命名空間,同一個實體反序列化時會出錯,改成Json就OK了。代碼如下:
using My.Log; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.IO; using System.Linq; using System.Net; using System.Runtime.Serialization.Formatters.Binary; using Newtonsoft.Json; namespace My.Redis { /// <summary> /// /// </summary> public static class RedisHelper { private static readonly string Coonstr = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; private static object _locker = new Object(); private static ConnectionMultiplexer _instance = null; /// <summary> /// 返回已連接的實例, /// </summary> public static ConnectionMultiplexer Instance { get { if (_instance == null) { lock (_locker) { if (_instance == null || !_instance.IsConnected) { _instance = ConnectionMultiplexer.Connect(Coonstr); } } } //注冊如下事件 _instance.ConnectionFailed += MuxerConnectionFailed; _instance.ConnectionRestored += MuxerConnectionRestored; _instance.ErrorMessage += MuxerErrorMessage; _instance.ConfigurationChanged += MuxerConfigurationChanged; _instance.HashSlotMoved += MuxerHashSlotMoved; _instance.InternalError += MuxerInternalError; return _instance; } } static RedisHelper() { } /// <summary> /// 獲取一個連接實例 /// </summary> /// <returns></returns> public static IDatabase GetDatabase() { return Instance.GetDatabase(); } /// <summary> /// 過期時間 /// </summary> /// <param name="Min">分鐘</param> /// <returns></returns> private static TimeSpan ExpireTimeSpan(double Min) { bool bl = bool.Parse(ConfigurationManager.AppSettings["UseRedis"]); if (bl) { return TimeSpan.FromMinutes(Min); } else { return TimeSpan.FromMilliseconds(1); } } /// <summary> /// 清除 包含特定字符的所有緩存 /// </summary> public static void RemoveSpeStr(string keyStr) { List<string> listKeys = GetAllKeys(); foreach (string k in listKeys) { if (k.Contains(keyStr)) { Remove(k); } } } /// <summary> /// 判斷在緩存中是否存在該key的緩存數據 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Exists(string key) { return GetDatabase().KeyExists(key); //可直接調用 } /// <summary> /// 移除指定key的緩存 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Remove(string key) { if (Exists(key)) { return GetDatabase().KeyDelete(key); } return false; } /// <summary> /// Set /// </summary> /// <typeparam name="T">類型</typeparam> /// <param name="key">鍵</param> /// <param name="t">值</param> /// <param name="timeout">多少分鐘後過期</param> /// <returns></returns> public static bool Set<T>(string key, T t, double minOut = 60*3) { return GetDatabase().StringSet(key, Serialize(t), ExpireTimeSpan(minOut)); } /// <summary> /// Get /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public static T Get<T>(string key) { return Deserialize<T>(GetDatabase().StringGet(key)); } /// <summary> /// DataSet 緩存 /// </summary> public static bool SetData(string key, DataSet ds, double minOut = 60*3) { return GetDatabase().StringSet(key, Serialize(ds), ExpireTimeSpan(minOut)); } /// <summary> /// 獲取 DataSet /// </summary> public static DataSet GetDataSet(string key) { return Deserialize<DataSet>(GetDatabase().StringGet(key)); } /// <summary> /// 刷新緩存 /// </summary> public static void FlushAll() { var endpoints = Instance.GetEndPoints(); var server = Instance.GetServer(endpoints.First()); server.FlushDatabase(); // to wipe a single database, 0 by default //server.FlushAllDatabases(); // to wipe all databases } /// <summary> /// 得到所有緩存鍵值 /// </summary> /// <returns></returns> public static List<string> GetAllKeys() { List<string> lstKey = new List<string>(); var endpoints = Instance.GetEndPoints(); var server = Instance.GetServer(endpoints.First()); var keys = server.Keys(); foreach (var key in keys) { lstKey.Add(key); } return lstKey; } //---------------------------------------------------------------------------------------------------------- static string JsonSerialize(object o) { if (o == null) { return null; } return JsonConvert.SerializeObject(o); } static T JsonDeserialize<T>(string json) { if (json == null) { return default(T); } return JsonConvert.DeserializeObject<T>(json); } /// <summary> /// 序列化對象 /// </summary> /// <param name="o"></param> /// <returns></returns> static byte[] Serialize(object o) { if (o == null) { return null; } BinaryFormatter binaryFormatter = new BinaryFormatter(); using (MemoryStream memoryStream = new MemoryStream()) { binaryFormatter.Serialize(memoryStream, o); byte[] objectDataAsStream = memoryStream.ToArray(); return objectDataAsStream; } } /// <summary> /// 反序列化對象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="stream"></param> /// <returns></returns> static T Deserialize<T>(byte[] stream) { if (stream == null) { return default(T); } BinaryFormatter binaryFormatter = new BinaryFormatter(); using (MemoryStream memoryStream = new MemoryStream(stream)) { T result = (T)binaryFormatter.Deserialize(memoryStream); return result; } } /// <summary> /// 配置更改時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) { LogHelper.LogExceRun("Configuration changed: " + e.EndPoint, new Exception()); } /// <summary> /// 發生錯誤時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) { LogHelper.LogExceRun("ErrorMessage: " + e.Message, new Exception()); } /// <summary> /// 重新建立連接之前的錯誤 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) { LogHelper.LogExceRun("ConnectionRestored: " + e.EndPoint, new Exception()); } /// <summary> /// 連接失敗 , 如果重新連接成功你將不會收到這個通知 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e) { LogHelper.LogExceRun("重新連接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)), new Exception()); } /// <summary> /// 更改集群 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e) { LogHelper.LogExceRun("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint, new Exception()); } /// <summary> /// redis類庫錯誤 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void MuxerInternalError(object sender, InternalErrorEventArgs e) { LogHelper.LogExceRun("InternalError:Message" + e.Exception.Message, new Exception()); } /// <summary> /// GetServer方法會接收一個EndPoint類或者一個唯一標識一台服務器的鍵值對 /// 有時候需要為單個服務器指定特定的命令 /// 使用IServer可以使用所有的shell命令,比如: /// DateTime lastSave = server.LastSave(); /// ClientInfo[] clients = server.ClientList(); /// 如果報錯在連接字符串後加 ,allowAdmin=true; /// </summary> /// <returns></returns> public static IServer GetServer(string host, int port) { IServer server = Instance.GetServer(host, port); return server; } /// <summary> /// 獲取全部終結點 /// </summary> /// <returns></returns> public static EndPoint[] GetEndPoints() { EndPoint[] endpoints = Instance.GetEndPoints(); return endpoints; } } }