var connStr = "localhost:6379,password="; var db = 2; SiteRedisHelper redisHelper = new SiteRedisHelper(connStr, "monster", db); var key = "MessageQueue"; var msg = string.Empty; #endregion
消息寫入+讀取(入門版)html
#region 添加消息 while (true) { Console.WriteLine("請輸入你須要發送的消息"); msg = Console.ReadLine(); if (!string.IsNullOrWhiteSpace(msg)) { // var listLeftPush = redisHelper.ListLeftPush(key, msg);//添加一條消息並返回已添加消息數量 var listLeftPushAsync = redisHelper.ListLeftPushAsync(key, msg);//異步添加 //追加事件 listLeftPushAsync.ContinueWith((task => { if (task.IsCompletedSuccessfully) { Console.WriteLine($"消息添加完畢,此消息隊列共有{task.Result}條信息"); } })); } else { Console.WriteLine("中止發送消息"); break; } }; #endregion #region 讀取消息 while (!string.IsNullOrWhiteSpace(msg = redisHelper.ListLeftPop(key))) { Console.WriteLine("消息出列:" + msg); Debug.WriteLine("消息出列:" + msg); FileLogTools.Write(msg, "RedisMSMQ.Try"); } #endregion
相對來講仍是挺簡單的,也沒有趕上什麼奇怪的異常,此處便不作什麼太多說明redis
將實體作爲消息進行寫入/讀取json
稍微改造了一下使用對象作爲消息進行寫入/讀取 <實體類> public class MsgEntity { public string Content { get; set; } public DateTimeOffset CreateTime { get; set; } } <添加相關> var msgCount = redisHelper.ListLeftPush<MsgEntity>(key,new MsgEntity() { Content = msg, CreateTime = DateTimeOffset.Now }); Console.WriteLine($"添加成功,消息站已有{msgCount}條消息"); <讀取的消息> 1.原始: ���� DRedisMSMQ.Try, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null RedisMSMQ.Try.Entity.MsgEntity <Content>k__BackingField<CreateTime>k__BackingFieldSystem.DateTimeOffset hello����System.DateTimeOffset DateTime OffsetMinutes 'NCN��� ... 一串亂碼 + 一堆命名空間 看來寫入須要調整 2.調整 : <old> private static byte[] Serialize(object obj) { try { if (obj == null) return null; var binaryFormatter = new BinaryFormatter(); using (var memoryStream = new MemoryStream()) { binaryFormatter.Serialize(memoryStream, obj); var data = memoryStream.ToArray(); return data; } } catch (SerializationException ex) { throw ex; } } <new> JsonConvert.SerializeObject(redisValue) 2.1 讀取一樣處理 <異常記錄> 1.添加時異常:System.Runtime.Serialization.SerializationException:「Type 'RedisMSMQ.Try.Entity.MsgEntity' in Assembly 'RedisMSMQ.Try, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.」 說明:此對象在程序集中不可進行序列化 處理:給類添加特性[Serializable]
使用實體時,處理也是很是簡單的,主要是注意一下轉string的方式,
我的使用的是JsonConvert 進行序列化/反序列化(json比較簡潔,工具類功能也比較齊全) 其次就是編碼一致api
模擬簡單的發佈/訂閱異步
#region 準備參數 var connStr = "localhost:6379,password="; var db = 2; SiteRedisHelper redisHelper = new SiteRedisHelper(connStr, "monster", db); var key = "entrepot"; var model = default(Produce); #endregion #region 審覈線程,訂閱申請消息,給予相應的處理 ThreadPool.QueueUserWorkItem((state => { Thread.Sleep(1000); while (IsDealValid) { var validMsg = redisHelper.ListRightPop<Produce>(key); if (validMsg != null && !validMsg.IsNull()) { Console.WriteLine($"正在審覈產品:{JsonConvert.SerializeObject(validMsg)}"); } } })); #endregion #region 主線程_添加產品 Console.WriteLine("歡迎來到產品中心,請填寫產品註冊資料"); IsDealValid = true; while ((model = Produce.RegisterProduce())!= null) { var validCount = redisHelper.ListLeftPush<Produce>(key, model);//將註冊資料添加到消息隊列中 Console.WriteLine($"產品註冊申請正在處理中……,在您以前共有{validCount-1}個產品正在處理,請耐心等待審覈結果"); } #endregion
發佈/訂閱工具
#region 訂閱消息 ThreadPool.QueueUserWorkItem((state => { redisHelper.Subscribe(channel, ((redisChannel, value) => { //Console.WriteLine($"訂閱方收到一條消息:{JsonConvert.SerializeObject(value)}"); if (!value.IsNullOrEmpty) { Console.WriteLine($"訂閱方收到一條消息:{value.ToString()}"); } })); Console.WriteLine("子線程已訂閱消息"); })); #endregion #region 主線程發佈消息 while ((model = Produce.RegisterProduce()) != null) { var receiveCount = redisHelper.Publish(channel, model); Console.WriteLine($"此條消息已被{receiveCount}我的訂閱"); } #endregion 發佈訂閱 vs 消息隊列 1. 消息隊列中的消息不能重複讀取,發佈訂閱中的消息由訂閱方共享 2. 若發佈時沒有訂閱方,後續加入的訂閱方將不能收到此條消息。在消息隊列中,若消息沒有及時出列,消息將會繼續保存在消息隊列中
總結編碼
整體來講,redis的操做都是比較簡單的,由於官方已經有集成api供咱們調用,因此操做起來仍是沒什麼難度,只須要了解方法的應用就能夠了,複雜一點的,應該就是業務流程的一些具體應用,應用場景的使用,效率的提高線程
相關類說明:code
SiteRedisHelperorm
參考博文:http://www.cnblogs.com/liqingwen/archive/2017/04/06/6672452.html
《構造方法》 public SiteRedisHelper(string connStr, string defaultKey, int db = -1) { //鏈接字符串 ConnectionString = connStr; //創建鏈接 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString); //默認前綴【無實用】 DefaultKey = defaultKey; //註冊相關事件 【未應用】 RegisterEvent(); //獲取Database操做對象 _db = _connMultiplexer.GetDatabase(db); }
author:monster
since:7/9/2018 11:25:14 AM
direction:redis mssq analysis