從 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;
}
}
}