博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习...
阅读量:6045 次
发布时间:2019-06-20

本文共 56621 字,大约阅读时间需要 188 分钟。

 

在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责。

首先我们要创建一个User类

1     public class User 2     { 3         private string name; 4         public string Name 5         { 6             get { return name; } 7             set { name = value; } 8         } 9         private string age;10         public string Age11         {12             get { return age; }13             set { age = value; }14         }15         private string sex;16         public string Sex17         {18             get { return sex; }19             set { sex = value; }20         }21     }

然后在Main函数中声明并初始化一个User对象

1             User userA = new User()2             {3                 Name = "李四",4                 Age = "25",5                 Sex = "男",6             };

因为要对比对象编辑前后的内容,所以需要备份一下这个UserA,我们来个深拷贝

1 User userB = DeepCopyByXml
(userA);
1         ///  2         /// 深拷贝 3         ///  4         /// 
5 /// 6 ///
7 public static T DeepCopyByXml
(T obj) where T : class 8 { 9 object retval;10 using (MemoryStream ms = new MemoryStream())11 {12 XmlSerializer xml = new XmlSerializer(typeof(T));13 xml.Serialize(ms, obj);14 ms.Seek(0, SeekOrigin.Begin);15 retval = xml.Deserialize(ms);16 ms.Close();17 }18 return (T)retval;19 }

接下来的工作是修改UserA的属性,然后和UserB对比,利用反射来实现该功能

///         /// Model对比        ///         /// 
/// /// private static void CompareModel
(T oldModel, T newModel) where T : class { string changeStr = string.Empty; PropertyInfo[] properties = oldModel.GetType().GetProperties(); Console.WriteLine("--------用户信息修改汇总--------"); foreach (System.Reflection.PropertyInfo item in properties) {string name = item.Name; object oldValue = item.GetValue(oldModel); object newValue = item.GetValue(newModel); if (!oldValue.Equals(newValue)) { Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]"); } } }

 从运行结果来看我们已经获取到了修改的内容,美中不足的是“Name”和“Age”,如何以中文显示属性名,接下来将利用C#的特性来实现

新建一个自定义的特性类TableAttribute

/*         参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。    参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。    参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。     */    [AttributeUsage(AttributeTargets.Class |    AttributeTargets.Field |    AttributeTargets.Property,          AllowMultiple = false,          Inherited = false)]    public class TableAttribute : System.Attribute    {        private string fieldName;        private string tableName;        ///         /// 表名        ///         public string TableName        {            get { return tableName; }            set { tableName = value; }        }        ///         /// 字段名        ///         public string FieldName        {            get { return fieldName; }            set { fieldName = value; }        }    }

接着修改User类,加上自定义的特性TableAttribute

///     /// 用户信息实体类    ///     [TableAttribute(TableName = "用户信息")]    public class User    {        private string name;        [TableAttribute(FieldName = "姓名")]        public string Name        {            get { return name; }            set { name = value; }        }        private string age;        [TableAttribute(FieldName = "年龄")]        public string Age        {            get { return age; }            set { age = value; }        }        private string sex;        [TableAttribute(FieldName = "性别")]        public string Sex        {            get { return sex; }            set { sex = value; }        }    }

最后修改一下CompareModel这个方法

1         ///  2         /// Model对比 3         ///  4         /// 
5 /// 6 /// 7 private static void CompareModel
(T oldModel, T newModel) where T : class 8 { 9 string changeStr = string.Empty;10 PropertyInfo[] properties = oldModel.GetType().GetProperties();11 Console.WriteLine("--------用户信息修改汇总--------");12 foreach (System.Reflection.PropertyInfo item in properties)13 {14 TableAttribute tableAttribute = item.GetCustomAttribute
();15 string name = item.Name;16 if (tableAttribute != null)17 name = tableAttribute.FieldName;18 object oldValue = item.GetValue(oldModel);19 object newValue = item.GetValue(newModel);20 if (!oldValue.Equals(newValue))21 {22 Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");23 }24 }25 }

我们看一下运行结果

 完整demo下载:

(完)

 

 

 

 

在之前介绍的火车票查询工具中,利用邮件和短信将查询结果推送给用户。免费短信的条数只有5条,用完之后只能单独使用邮件提醒。

最近发现腾讯云的福利,简单的介绍一下用法。

 

 

 

 

 

 

 

 

 

 

腾讯云-》产品-》通信服务-》短信-》开通服务-》添加应用-》创建签名和模板-》等待审核通过-》按照Demo测试

 

 

在整个流程中,最耗时的就是创建签名和模板,对个人来说只能选择app、公众号或小程序的方式进行申请,多亏之前折腾过一点小程序,从而闯关成功。

接下来查看官方Demo 

整理后的测试Demo

调用代码:

1 using QcloudSms; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace ConsoleTest 9 {10     class SmsSDKDemo11     {12         /// 13         /// appId14         /// 15         private static int appId = 140xxxxx;16         /// 17         /// appKey18         /// 19         private static string appKey = "xxxxxxxxxxxxxxx";20         /// 21         /// 接收手机号22         /// 23         private static string phoneNumber = "xxxxxxxx";24         /// 25         /// 短信模板ID26         /// 27         private static int tmplateId = xxxxxxx;28 29         static void Main(string[] args)30         {31             try32             {33                 SmsSingleSenderResult singleResult;34                 SmsSingleSender singleSender = new SmsSingleSender(appId, appKey);35 36                 singleResult = singleSender.Send(SmsType.普通短信, phoneNumber, "");37                 Console.WriteLine(singleResult);38 39                 List
templParams = new List
();40 templParams.Add("G2619");41 templParams.Add("二等座:23 无座:128");42 singleResult = singleSender.SendWithParam(phoneNumber, tmplateId, templParams);43 Console.WriteLine(singleResult);44 }45 catch (Exception e)46 {47 Console.WriteLine(e);48 }49 Console.Read();50 }51 }52 }
1 namespace QcloudSms  2 {  3     #region 短信类型枚举  4     ///   5     /// 短信类型枚举  6     ///   7     public enum SmsType  8     {  9         普通短信 = 0, 10         营销短信 = 1 11     } 12     #endregion 13  14     #region 单发 15     ///  16     /// 单发 17     ///  18     class SmsSingleSender 19     { 20         #region 变量 21         ///  22         /// appId 23         ///  24         private int appId; 25         ///  26         /// appkey 27         ///  28         private string appkey; 29         ///  30         /// url 31         ///  32         private string url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms"; 33         ///  34         /// util 35         ///  36         private SmsSenderUtil util = new SmsSenderUtil(); 37         #endregion 38  39         #region 构造 40         ///  41         /// 构造函数 42         ///  43         ///  44         ///  45         public SmsSingleSender(int sdkappid, string appkey) 46         { 47             this.appId = sdkappid; 48             this.appkey = appkey; 49         } 50         #endregion 51  52         #region 普通单发短信接口 53         ///  54         /// 普通单发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名 55         ///  56         /// 短信类型,0 为普通短信,1 营销短信 57         /// 不带国家码的手机号 58         /// 信息内容,必须与申请的模板格式一致,否则将返回错误 59         /// 短信码号扩展号,格式为纯数字串,其他格式无效。默认没有开通 60         /// 服务端原样返回的参数,可填空 61         /// 
SmsSingleSenderResult
62 public SmsSingleSenderResult Send(SmsType type, string phoneNumber, string msg, string extend = "", string ext = "") 63 { 64 long random = util.GetRandom(); 65 long curTime = util.GetCurTime(); 66 67 // 按照协议组织 post 请求包体 68 JObject tel = new JObject(); 69 tel.Add("nationcode", SmsSenderUtil.nationCode); 70 tel.Add("mobile", phoneNumber); 71 JObject data = new JObject(); 72 data.Add("tel", tel); 73 data.Add("msg", msg); 74 data.Add("type", (int)type); 75 data.Add("sig", util.StrToHash(string.Format("appkey={0}&random={1}&time={2}&mobile={3}", appkey, random, curTime, phoneNumber))); 76 data.Add("time", curTime); 77 data.Add("extend", extend); 78 data.Add("ext", ext); 79 80 string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random; 81 HttpWebRequest request = util.GetPostHttpConn(wholeUrl); 82 byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); 83 request.ContentLength = requestData.Length; 84 Stream requestStream = request.GetRequestStream(); 85 requestStream.Write(requestData, 0, requestData.Length); 86 requestStream.Close(); 87 88 // 接收返回包 89 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 90 Stream responseStream = response.GetResponseStream(); 91 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); 92 string responseStr = streamReader.ReadToEnd(); 93 streamReader.Close(); 94 responseStream.Close(); 95 SmsSingleSenderResult result; 96 if (HttpStatusCode.OK == response.StatusCode) 97 { 98 result = util.ResponseStrToSingleSenderResult(responseStr); 99 }100 else101 {102 result = new SmsSingleSenderResult();103 result.result = -1;104 result.errmsg = "http error " + response.StatusCode + " " + responseStr;105 }106 return result;107 }108 #endregion109 110 #region 指定模板单发111 /// 112 /// 指定模板单发113 /// 114 /// 不带国家码的手机号115 /// 模板 id116 /// 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数117 /// 短信签名,如果使用默认签名,该字段可缺省118 /// 扩展码,可填空119 /// 服务端原样返回的参数,可填空120 ///
SmsSingleSenderResult
121 public SmsSingleSenderResult SendWithParam(string phoneNumber, int templId, List
templParams, string sign = "", string extend = "", string ext = "")122 {123 long random = util.GetRandom();124 long curTime = util.GetCurTime();125 126 // 按照协议组织 post 请求包体127 JObject tel = new JObject();128 tel.Add("nationcode", SmsSenderUtil.nationCode);129 tel.Add("mobile", phoneNumber);130 JObject data = new JObject();131 data.Add("tel", tel);132 data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumber));133 data.Add("tpl_id", templId);134 data.Add("params", util.SmsParamsToJSONArray(templParams));135 data.Add("sign", sign);136 data.Add("time", curTime);137 data.Add("extend", extend);138 data.Add("ext", ext);139 140 string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;141 HttpWebRequest request = util.GetPostHttpConn(wholeUrl);142 byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));143 request.ContentLength = requestData.Length;144 Stream requestStream = request.GetRequestStream();145 requestStream.Write(requestData, 0, requestData.Length);146 requestStream.Close();147 148 // 接收返回包149 HttpWebResponse response = (HttpWebResponse)request.GetResponse();150 Stream responseStream = response.GetResponseStream();151 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));152 string responseStr = streamReader.ReadToEnd();153 streamReader.Close();154 responseStream.Close();155 SmsSingleSenderResult result;156 if (HttpStatusCode.OK == response.StatusCode)157 {158 result = util.ResponseStrToSingleSenderResult(responseStr);159 }160 else161 {162 result = new SmsSingleSenderResult();163 result.result = -1;164 result.errmsg = "http error " + response.StatusCode + " " + responseStr;165 }166 return result;167 }168 #endregion169 }170 #endregion171 172 #region 单发结果173 ///
174 /// 单发结果175 /// 176 class SmsSingleSenderResult177 {178 ///
179 /// 错误码,0 表示成功(计费依据),非 0 表示失败180 /// 181 public int result { set; get; }182 ///
183 /// 错误消息,result 非 0 时的具体错误信息184 /// 185 public string errmsg { set; get; }186 ///
187 /// 用户的 session 内容,腾讯 server 回包中会原样返回188 /// 189 public string ext { set; get; }190 ///
191 /// 本次发送标识 id,标识一次短信下发记录192 /// 193 public string sid { set; get; }194 ///
195 /// 短信计费的条数196 /// 197 public int fee { set; get; }198 ///
199 /// ToString()200 /// 201 ///
202 public override string ToString()203 {204 return string.Format("SmsSingleSenderResult\nresult {0}\nerrMsg {1}\next {2}\nsid {3}\nfee {4}", result, errmsg, ext, sid, fee);205 }206 }207 #endregion208 209 #region 群发210 ///
211 /// 群发212 /// 213 class SmsMultiSender214 {215 #region 变量216 ///
217 /// appId218 /// 219 private int appId;220 ///
221 /// appkey222 /// 223 private string appkey;224 ///
225 /// url226 /// 227 private string url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";228 ///
229 /// util230 /// 231 private SmsSenderUtil util = new SmsSenderUtil();232 #endregion233 234 #region 构造235 ///
236 /// 构造237 /// 238 ///
239 ///
240 public SmsMultiSender(int sdkappid, string appkey)241 {242 this.appId = sdkappid;243 this.appkey = appkey;244 }245 #endregion246 247 #region 普通群发短信接口248 ///
249 /// 普通群发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名250 ///【注意】 海外短信无群发功能251 /// 252 ///
短信类型,0 为普通短信,1 营销短信253 ///
254 ///
不带国家码的手机号列表255 ///
信息内容,必须与申请的模板格式一致,否则将返回错误256 ///
扩展码,可填空257 ///
服务端原样返回的参数,可填空258 ///
SmsMultiSenderResult
259 public SmsMultiSenderResult Send(SmsType type, List
phoneNumbers, string msg, string extend = "", string ext = "")260 {261 long random = util.GetRandom();262 long curTime = util.GetCurTime();263 264 // 按照协议组织 post 请求包体265 JObject data = new JObject();266 data.Add("tel", util.PhoneNumbersToJSONArray(SmsSenderUtil.nationCode, phoneNumbers));267 data.Add("type", (int)type);268 data.Add("msg", msg);269 data.Add("sig", util.CalculateSig(appkey, random, curTime, phoneNumbers));270 data.Add("time", curTime);271 data.Add("extend", extend);272 data.Add("ext", ext);273 274 string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;275 HttpWebRequest request = util.GetPostHttpConn(wholeUrl);276 byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));277 request.ContentLength = requestData.Length;278 Stream requestStream = request.GetRequestStream();279 requestStream.Write(requestData, 0, requestData.Length);280 requestStream.Close();281 282 // 接收返回包283 HttpWebResponse response = (HttpWebResponse)request.GetResponse();284 Stream responseStream = response.GetResponseStream();285 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));286 string responseStr = streamReader.ReadToEnd();287 streamReader.Close();288 responseStream.Close();289 SmsMultiSenderResult result;290 if (HttpStatusCode.OK == response.StatusCode)291 {292 result = util.ResponseStrToMultiSenderResult(responseStr);293 }294 else295 {296 result = new SmsMultiSenderResult();297 result.result = -1;298 result.errmsg = "http error " + response.StatusCode + " " + responseStr;299 }300 return result;301 }302 #endregion303 304 #region 指定模板群发305 ///
306 /// 指定模板群发307 /// 【注意】海外短信无群发功能308 /// 309 ///
不带国家码的手机号列表310 ///
模板 id311 ///
模板参数列表312 ///
签名,如果填空,系统会使用默认签名313 ///
扩展码,可以填空314 ///
服务端原样返回的参数,可以填空315 ///
SmsMultiSenderResult
316 public SmsMultiSenderResult SendWithParam(List
phoneNumbers, int templId, List
templParams, string sign = "", string extend = "", string ext = "")317 {318 long random = util.GetRandom();319 long curTime = util.GetCurTime();320 321 // 按照协议组织 post 请求包体322 JObject data = new JObject();323 data.Add("tel", util.PhoneNumbersToJSONArray(SmsSenderUtil.nationCode, phoneNumbers));324 data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumbers));325 data.Add("tpl_id", templId);326 data.Add("params", util.SmsParamsToJSONArray(templParams));327 data.Add("sign", sign);328 data.Add("time", curTime);329 data.Add("extend", extend);330 data.Add("ext", ext);331 332 string wholeUrl = url + "?sdkappid=" + appId + "&random=" + random;333 HttpWebRequest request = util.GetPostHttpConn(wholeUrl);334 byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));335 request.ContentLength = requestData.Length;336 Stream requestStream = request.GetRequestStream();337 requestStream.Write(requestData, 0, requestData.Length);338 requestStream.Close();339 340 // 接收返回包341 HttpWebResponse response = (HttpWebResponse)request.GetResponse();342 Stream responseStream = response.GetResponseStream();343 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));344 string responseStr = streamReader.ReadToEnd();345 streamReader.Close();346 responseStream.Close();347 SmsMultiSenderResult result;348 if (HttpStatusCode.OK == response.StatusCode)349 {350 result = util.ResponseStrToMultiSenderResult(responseStr);351 }352 else353 {354 result = new SmsMultiSenderResult();355 result.result = -1;356 result.errmsg = "http error " + response.StatusCode + " " + responseStr;357 }358 return result;359 }360 #endregion361 }362 #endregion363 364 #region 群发结果365 ///
366 /// 群发结果367 /// 368 class SmsMultiSenderResult369 {370 public class Detail371 {372 ///
373 /// 错误码,0 表示成功(计费依据),非 0 表示失败374 /// 375 public int result { get; set; }376 ///
377 /// 错误消息,result 非 0 时的具体错误信息378 /// 379 public string errmsg { get; set; }380 ///
381 /// 手机号码382 /// 383 public string mobile { get; set; }384 ///
385 /// 国家码386 /// 387 public string nationcode { get; set; }388 ///
389 /// 本次发送标识 id,标识一次短信下发记录390 /// 391 public string sid { get; set; }392 ///
393 /// 短信计费的条数394 /// 395 public int fee { get; set; }396 ///
397 /// ToString()398 /// 399 ///
400 public override string ToString()401 {402 return string.Format(403 "\tDetail result {0} errmsg {1} mobile {2} nationcode {3} sid {4} fee {5}",404 result, errmsg, mobile, nationcode, sid, fee);405 }406 }407 408 public int result;409 public string errmsg = "";410 public string ext = "";411 public IList
detail;412 413 public override string ToString()414 {415 if (null != detail)416 {417 return String.Format(418 "SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\ndetail:\n{3}",419 result, errmsg, ext, String.Join("\n", detail));420 }421 else422 {423 return String.Format(424 "SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\n",425 result, errmsg, ext);426 }427 }428 }429 #endregion430 431 #region 公共类432 ///
433 /// 公共类434 /// 435 class SmsSenderUtil436 {437 ///
438 /// 国家码439 /// 440 public static string nationCode = "86";441 ///
442 /// 随机数生成器443 /// 444 private Random random = new Random();445 446 #region GetPostHttpConn447 ///
448 /// GetPostHttpConn449 /// 450 ///
451 ///
452 public HttpWebRequest GetPostHttpConn(string url)453 {454 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);455 request.Method = "POST";456 request.ContentType = "application/x-www-form-urlencoded";457 return request;458 }459 #endregion460 461 #region 生成随机数462 ///
463 /// 生成随机数464 /// 465 ///
466 public long GetRandom()467 {468 return random.Next(999999) % 900000 + 100000;469 }470 #endregion471 472 #region 获取请求发起时间473 ///
474 /// 获取请求发起时间,475 /// unix 时间戳(单位:秒),如果和系统时间相差超过 10 分钟则会返回失败476 /// 477 ///
478 public long GetCurTime()479 {480 Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;481 return unixTimestamp;482 }483 #endregion484 485 #region 字符串转SHA256486 ///
487 /// 字符串转SHA256488 /// 489 ///
490 ///
491 public string StrToHash(string str)492 {493 SHA256 sha256 = SHA256Managed.Create();494 byte[] resultByteArray = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));495 return ByteArrayToHex(resultByteArray);496 }497 498 ///
499 /// 将二进制的数值转换为 16 进制字符串,如 "abc" => "616263"500 /// 501 ///
502 ///
503 private static string ByteArrayToHex(byte[] byteArray)504 {505 string returnStr = "";506 if (byteArray != null)507 {508 for (int i = 0; i < byteArray.Length; i++)509 {510 returnStr += byteArray[i].ToString("x2");511 }512 }513 return returnStr;514 }515 #endregion516 517 #region 将单发回包解析成结果对象518 ///
519 /// 将单发回包解析成结果对象520 /// 521 ///
522 ///
523 public SmsSingleSenderResult ResponseStrToSingleSenderResult(string str)524 {525 SmsSingleSenderResult result = JsonConvert.DeserializeObject
(str);526 return result;527 }528 #endregion529 530 #region 将群发回包解析成结果对象531 ///
532 /// 将群发回包解析成结果对象533 /// 534 ///
535 ///
536 public SmsMultiSenderResult ResponseStrToMultiSenderResult(string str)537 {538 SmsMultiSenderResult result = JsonConvert.DeserializeObject
(str);539 return result;540 }541 #endregion542 543 #region List
转JArray544 ///
545 /// List
转JArray546 ///
547 ///
548 ///
549 public JArray SmsParamsToJSONArray(List
templParams)550 {551 JArray smsParams = new JArray();552 foreach (string templParamsElement in templParams)553 {554 smsParams.Add(templParamsElement);555 }556 return smsParams;557 }558 #endregion559 560 #region PhoneNumbersToJSONArray561 ///
562 /// PhoneNumbersToJSONArray563 /// 564 ///
565 ///
566 ///
567 public JArray PhoneNumbersToJSONArray(string nationCode, List
phoneNumbers)568 {569 JArray tel = new JArray();570 int i = 0;571 do572 {573 JObject telElement = new JObject();574 telElement.Add("nationcode", nationCode);575 telElement.Add("mobile", phoneNumbers.ElementAt(i));576 tel.Add(telElement);577 } while (++i < phoneNumbers.Count);578 return tel;579 }580 #endregion581 582 #region 计算App凭证583 /*584 "sig" 字段根据公式 sha256(appkey=$appkey&random=$random&time=$time&mobile=$mobile)生成585 */586 public string CalculateSigForTempl(string appkey, long random, long curTime, List
phoneNumbers)587 {588 string phoneNumbersString = phoneNumbers.ElementAt(0);589 for (int i = 1; i < phoneNumbers.Count; i++)590 {591 phoneNumbersString += "," + phoneNumbers.ElementAt(i);592 }593 return StrToHash(String.Format(594 "appkey={0}&random={1}&time={2}&mobile={3}",595 appkey, random, curTime, phoneNumbersString));596 }597 598 public string CalculateSigForTempl(string appkey, long random, long curTime, string phoneNumber)599 {600 List
phoneNumbers = new List
();601 phoneNumbers.Add(phoneNumber);602 return CalculateSigForTempl(appkey, random, curTime, phoneNumbers);603 }604 605 public string CalculateSig(string appkey, long random, long curTime, List
phoneNumbers)606 {607 string phoneNumbersString = phoneNumbers.ElementAt(0);608 for (int i = 1; i < phoneNumbers.Count; i++)609 {610 phoneNumbersString += "," + phoneNumbers.ElementAt(i);611 }612 return StrToHash(String.Format(613 "appkey={0}&random={1}&time={2}&mobile={3}",614 appkey, random, curTime, phoneNumbersString));615 }616 #endregion617 }618 #endregion619 }

demo下载路径为:

 

 

 

 

 

Redis下载地址:

下载msi格式的安装文件。

 

1.运行安装程序,单击next按钮。

 

2.勾选接受许可协议中的条款,单击next按钮。

 

3.选择安装目录,勾选添加到环境变量,单击next按钮。

 

4.端口号以及防火墙添加例外,单击next按钮。

 

5.是否设置最大内存限制,默认不勾选,单击next按钮。

 

6.开始安装,单击Insatll按钮。

 

7.等待安装,耗时不超过一分钟。

 

8.安装完成,单击Finsh按钮。

 

9.安装目录文件如下所示。

 

10.可以从服务中查看到redis服务已经正常运行。

 

 

 

 

 

 

一、软件安装

Redis下载地址:

因为官方并不支持windows系统,需要从微软的GitHub上下载。

解压缩后文件夹内容如图所示(版本3.2.100):

最开始会用到的文件有redis-server.exe、redis-cli.exe以及一个配置文件redis.windows.conf。

1)启动redis服务,运行cmd.exe

 进入到redis文件夹

cd desttop/redis

 启动redis-server.exe 并使用配置文件,出现如下图所示就是启动成功了。

redis-server.exe redis.windows.conf

2)启动客户端,再打开一个cmd.exe

 进入到文件夹后启动redis-cli.exe

redis-cli.exe

国际惯例,ping helloworld ,解锁熟练掌握redis的成就。

 

3)为什么默认使用6379端口

Redis作者antirez同学在twitter上说将在下一篇博文()中向大家解释为什么他选择6379作为默认端口号。而现在这篇博文出炉,在解释了Redis的LRU机制之后,如期向大家解释了采用6379作为默认端口的原因。6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。

二、基本用法

redis是以kev-value形式进行数据存储的,value有字符串、哈希表、列表、集合、有序集合等。

一些命令的使用,可以参考学习。

配置文件的使用,redis.windows-service.conf(以windows服务运行时修改),

1.密码修改 # requirepass foobared //去掉注释#,将foobared替换为你自己的密码 2.文件命名修改 dbfilename dump.rdb // xxxx.rdb

三、C#使用Redis

1)使用到的第三方dll:

2)搜集到的RedisHelper方法,增加了批量操作

1 ///    2     /// Redis操作   3     ///    4     public class RedisHelper   5     {   6         ///    7         /// 连接redis库的Number   8         ///    9         private int DbNum { set; get; }  10         private readonly ConnectionMultiplexer _conn;  11         ///   12         /// 自定义键前缀  13         ///   14         public string CustomKey;  15   16         #region 构造函数  17   18         public RedisHelper(int dbNum = 0)  19             : this(dbNum, null)  20         {  21         }  22   23         public RedisHelper(int dbNum, string readWriteHosts)  24         {  25             DbNum = dbNum;  26             _conn =  27                 string.IsNullOrWhiteSpace(readWriteHosts) ?  28                 RedisConnectionHelp.Instance :  29                 RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts);  30         }  31   32         #endregion 构造函数  33   34         #region String  35   36         #region 同步方法  37   38         ///   39         /// 保存单个key value  40         ///   41         /// Redis Key  42         /// 保存的值  43         /// 过期时间  44         /// 
45 public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 46 { 47 key = AddSysCustomKey(key); 48 return Do(db => db.StringSet(key, value, expiry)); 49 } 50 51 /// 52 /// 保存多个key value 53 /// 54 /// 键值对 55 ///
56 public bool StringSet(List
> keyValues) 57 { 58 List
> newkeyValues = 59 keyValues.Select(p => new KeyValuePair
(AddSysCustomKey(p.Key), p.Value)).ToList(); 60 return Do(db => db.StringSet(newkeyValues.ToArray())); 61 } 62 63 ///
64 /// 保存一个对象 65 /// 66 ///
67 ///
68 ///
69 ///
70 ///
71 public bool StringSet
(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 72 { 73 key = AddSysCustomKey(key); 74 string json = ConvertJson(obj); 75 return Do(db => db.StringSet(key, json, expiry)); 76 } 77 78 ///
79 /// 获取单个key的值 80 /// 81 ///
Redis Key 82 ///
83 public byte[] StringGet(string key) 84 { 85 key = AddSysCustomKey(key); 86 return Do(db => db.StringGet(key)); 87 } 88 89 ///
90 /// 获取多个Key 91 /// 92 ///
Redis Key集合 93 ///
94 public RedisValue[] StringGet(List
listKey) 95 { 96 List
newKeys = listKey.Select(AddSysCustomKey).ToList(); 97 return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); 98 } 99 100 ///
101 /// 获取一个key的对象 102 /// 103 ///
104 ///
105 ///
106 public T StringGet
(string key) 107 { 108 key = AddSysCustomKey(key); 109 return Do(db => ConvertObj
(db.StringGet(key))); 110 } 111 112 public object StringGetObj(string key) 113 { 114 key = AddSysCustomKey(key); 115 var database = _conn.GetDatabase(DbNum); 116 return database.StringGet(key); 117 } 118 119 public static object GetObjFromBytes(byte[] buffer) 120 { 121 using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buffer)) 122 { 123 stream.Position = 0; 124 System.Runtime.Serialization.IFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 125 Object reobj = bf.Deserialize(stream); 126 return reobj; 127 } 128 } 129 130 ///
131 /// 为数字增长val 132 /// 133 ///
134 ///
可以为负 135 ///
增长后的值
136 public double StringIncrement(string key, double val = 1) 137 { 138 key = AddSysCustomKey(key); 139 return Do(db => db.StringIncrement(key, val)); 140 } 141 142 ///
143 /// 为数字减少val 144 /// 145 ///
146 ///
可以为负 147 ///
减少后的值
148 public double StringDecrement(string key, double val = 1) 149 { 150 key = AddSysCustomKey(key); 151 return Do(db => db.StringDecrement(key, val)); 152 } 153 154 #endregion 同步方法 155 156 #region 异步方法 157 158 ///
159 /// 保存单个key value 160 /// 161 ///
Redis Key 162 ///
保存的值 163 ///
过期时间 164 ///
165 public async Task
StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 166 { 167 key = AddSysCustomKey(key); 168 return await Do(db => db.StringSetAsync(key, value, expiry)); 169 } 170 171 ///
172 /// 保存多个key value 173 /// 174 ///
键值对 175 ///
176 public async Task
StringSetAsync(List
> keyValues) 177 { 178 List
> newkeyValues = 179 keyValues.Select(p => new KeyValuePair
(AddSysCustomKey(p.Key), p.Value)).ToList(); 180 return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); 181 } 182 183 ///
184 /// 保存一个对象 185 /// 186 ///
187 ///
188 ///
189 ///
190 ///
191 public async Task
StringSetAsync
(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 192 { 193 key = AddSysCustomKey(key); 194 string json = ConvertJson(obj); 195 return await Do(db => db.StringSetAsync(key, json, expiry)); 196 } 197 198 ///
199 /// 获取单个key的值 200 /// 201 ///
Redis Key 202 ///
203 public async Task
StringGetAsync(string key) 204 { 205 key = AddSysCustomKey(key); 206 return await Do(db => db.StringGetAsync(key)); 207 } 208 209 ///
210 /// 获取多个Key 211 /// 212 ///
Redis Key集合 213 ///
214 public async Task
StringGetAsync(List
listKey) 215 { 216 List
newKeys = listKey.Select(AddSysCustomKey).ToList(); 217 return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys))); 218 } 219 220 ///
221 /// 获取一个key的对象 222 /// 223 ///
224 ///
225 ///
226 public async Task
StringGetAsync
(string key) 227 { 228 key = AddSysCustomKey(key); 229 string result = await Do(db => db.StringGetAsync(key)); 230 return ConvertObj
(result); 231 } 232 233 ///
234 /// 为数字增长val 235 /// 236 ///
237 ///
可以为负 238 ///
增长后的值
239 public async Task
StringIncrementAsync(string key, double val = 1) 240 { 241 key = AddSysCustomKey(key); 242 return await Do(db => db.StringIncrementAsync(key, val)); 243 } 244 245 ///
246 /// 为数字减少val 247 /// 248 ///
249 ///
可以为负 250 ///
减少后的值
251 public async Task
StringDecrementAsync(string key, double val = 1) 252 { 253 key = AddSysCustomKey(key); 254 return await Do(db => db.StringDecrementAsync(key, val)); 255 } 256 257 #endregion 异步方法 258 259 #endregion String 260 261 #region Hash 262 263 #region 同步方法 264 265 ///
266 /// 判断某个数据是否已经被缓存 267 /// 268 ///
269 ///
270 ///
271 public bool HashExists(string key, string dataKey) 272 { 273 key = AddSysCustomKey(key); 274 return Do(db => db.HashExists(key, dataKey)); 275 } 276 277 ///
278 /// 存储数据到hash表 279 /// 280 ///
281 ///
282 ///
283 ///
284 ///
285 public bool HashSet
(string key, string dataKey, T t) 286 { 287 key = AddSysCustomKey(key); 288 return Do(db => 289 { 290 string json = ConvertJson(t); 291 return db.HashSet(key, dataKey, json); 292 }); 293 } 294 295 ///
296 /// 移除hash中的某值 297 /// 298 ///
299 ///
300 ///
301 public bool HashDelete(string key, string dataKey) 302 { 303 key = AddSysCustomKey(key); 304 return Do(db => db.HashDelete(key, dataKey)); 305 } 306 307 ///
308 /// 移除hash中的多个值 309 /// 310 ///
311 ///
312 ///
313 public long HashDelete(string key, List
dataKeys) 314 { 315 key = AddSysCustomKey(key); 316 //List
dataKeys1 = new List
() {"1","2"}; 317 return Do(db => db.HashDelete(key, dataKeys.ToArray())); 318 } 319 320 ///
321 /// 从hash表获取数据 322 /// 323 ///
324 ///
325 ///
326 ///
327 public T HashGet
(string key, string dataKey) 328 { 329 key = AddSysCustomKey(key); 330 return Do(db => 331 { 332 string value = db.HashGet(key, dataKey); 333 return ConvertObj
(value); 334 }); 335 } 336 337 ///
338 /// 为数字增长val 339 /// 340 ///
341 ///
342 ///
可以为负 343 ///
增长后的值
344 public double HashIncrement(string key, string dataKey, double val = 1) 345 { 346 key = AddSysCustomKey(key); 347 return Do(db => db.HashIncrement(key, dataKey, val)); 348 } 349 350 ///
351 /// 为数字减少val 352 /// 353 ///
354 ///
355 ///
可以为负 356 ///
减少后的值
357 public double HashDecrement(string key, string dataKey, double val = 1) 358 { 359 key = AddSysCustomKey(key); 360 return Do(db => db.HashDecrement(key, dataKey, val)); 361 } 362 363 ///
364 /// 获取hashkey所有Redis key 365 /// 366 ///
367 ///
368 ///
369 public List
HashKeys
(string key) 370 { 371 key = AddSysCustomKey(key); 372 return Do(db => 373 { 374 RedisValue[] values = db.HashKeys(key); 375 return ConvetList
(values); 376 }); 377 } 378 379 #endregion 同步方法 380 381 #region 异步方法 382 383 ///
384 /// 判断某个数据是否已经被缓存 385 /// 386 ///
387 ///
388 ///
389 public async Task
HashExistsAsync(string key, string dataKey) 390 { 391 key = AddSysCustomKey(key); 392 return await Do(db => db.HashExistsAsync(key, dataKey)); 393 } 394 395 ///
396 /// 存储数据到hash表 397 /// 398 ///
399 ///
400 ///
401 ///
402 ///
403 public async Task
HashSetAsync
(string key, string dataKey, T t) 404 { 405 key = AddSysCustomKey(key); 406 return await Do(db => 407 { 408 string json = ConvertJson(t); 409 return db.HashSetAsync(key, dataKey, json); 410 }); 411 } 412 413 ///
414 /// 移除hash中的某值 415 /// 416 ///
417 ///
418 ///
419 public async Task
HashDeleteAsync(string key, string dataKey) 420 { 421 key = AddSysCustomKey(key); 422 return await Do(db => db.HashDeleteAsync(key, dataKey)); 423 } 424 425 ///
426 /// 移除hash中的多个值 427 /// 428 ///
429 ///
430 ///
431 public async Task
HashDeleteAsync(string key, List
dataKeys) 432 { 433 key = AddSysCustomKey(key); 434 //List
dataKeys1 = new List
() {"1","2"}; 435 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); 436 } 437 438 ///
439 /// 从hash表获取数据 440 /// 441 ///
442 ///
443 ///
444 ///
445 public async Task
HashGeAsync
(string key, string dataKey) 446 { 447 key = AddSysCustomKey(key); 448 string value = await Do(db => db.HashGetAsync(key, dataKey)); 449 return ConvertObj
(value); 450 } 451 452 ///
453 /// 为数字增长val 454 /// 455 ///
456 ///
457 ///
可以为负 458 ///
增长后的值
459 public async Task
HashIncrementAsync(string key, string dataKey, double val = 1) 460 { 461 key = AddSysCustomKey(key); 462 return await Do(db => db.HashIncrementAsync(key, dataKey, val)); 463 } 464 465 ///
466 /// 为数字减少val 467 /// 468 ///
469 ///
470 ///
可以为负 471 ///
减少后的值
472 public async Task
HashDecrementAsync(string key, string dataKey, double val = 1) 473 { 474 key = AddSysCustomKey(key); 475 return await Do(db => db.HashDecrementAsync(key, dataKey, val)); 476 } 477 478 ///
479 /// 获取hashkey所有Redis key 480 /// 481 ///
482 ///
483 ///
484 public async Task
> HashKeysAsync
(string key) 485 { 486 key = AddSysCustomKey(key); 487 RedisValue[] values = await Do(db => db.HashKeysAsync(key)); 488 return ConvetList
(values); 489 } 490 491 #endregion 异步方法 492 493 #endregion Hash 494 495 #region List 496 497 #region 同步方法 498 499 ///
500 /// 移除指定ListId的内部List的值 501 /// 502 ///
503 ///
504 public void ListRemove
(string key, T value) 505 { 506 key = AddSysCustomKey(key); 507 Do(db => db.ListRemove(key, ConvertJson(value))); 508 } 509 510 ///
511 /// 获取指定key的List 512 /// 513 ///
514 ///
515 public List
ListRange
(string key) 516 { 517 key = AddSysCustomKey(key); 518 return Do(redis => 519 { 520 var values = redis.ListRange(key); 521 return ConvetList
(values); 522 }); 523 } 524 525 ///
526 /// 入队 527 /// 528 ///
529 ///
530 public void ListRightPush
(string key, T value) 531 { 532 key = AddSysCustomKey(key); 533 Do(db => db.ListRightPush(key, ConvertJson(value))); 534 } 535 536 ///
537 /// 出队 538 /// 539 ///
540 ///
541 ///
542 public T ListRightPop
(string key) 543 { 544 key = AddSysCustomKey(key); 545 return Do(db => 546 { 547 var value = db.ListRightPop(key); 548 return ConvertObj
(value); 549 }); 550 } 551 552 ///
553 /// 入栈 554 /// 555 ///
556 ///
557 ///
558 public void ListLeftPush
(string key, T value) 559 { 560 key = AddSysCustomKey(key); 561 Do(db => db.ListLeftPush(key, ConvertJson(value))); 562 } 563 564 ///
565 /// 出栈 566 /// 567 ///
568 ///
569 ///
570 public T ListLeftPop
(string key) 571 { 572 key = AddSysCustomKey(key); 573 return Do(db => 574 { 575 var value = db.ListLeftPop(key); 576 return ConvertObj
(value); 577 }); 578 } 579 580 ///
581 /// 获取集合中的数量 582 /// 583 ///
584 ///
585 public long ListLength(string key) 586 { 587 key = AddSysCustomKey(key); 588 return Do(redis => redis.ListLength(key)); 589 } 590 591 #endregion 同步方法 592 593 #region 异步方法 594 595 ///
596 /// 移除指定ListId的内部List的值 597 /// 598 ///
599 ///
600 public async Task
ListRemoveAsync
(string key, T value) 601 { 602 key = AddSysCustomKey(key); 603 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); 604 } 605 606 ///
607 /// 获取指定key的List 608 /// 609 ///
610 ///
611 public async Task
> ListRangeAsync
(string key) 612 { 613 key = AddSysCustomKey(key); 614 var values = await Do(redis => redis.ListRangeAsync(key)); 615 return ConvetList
(values); 616 } 617 618 ///
619 /// 入队 620 /// 621 ///
622 ///
623 public async Task
ListRightPushAsync
(string key, T value) 624 { 625 key = AddSysCustomKey(key); 626 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); 627 } 628 629 ///
630 /// 出队 631 /// 632 ///
633 ///
634 ///
635 public async Task
ListRightPopAsync
(string key) 636 { 637 key = AddSysCustomKey(key); 638 var value = await Do(db => db.ListRightPopAsync(key)); 639 return ConvertObj
(value); 640 } 641 642 ///
643 /// 入栈 644 /// 645 ///
646 ///
647 ///
648 public async Task
ListLeftPushAsync
(string key, T value) 649 { 650 key = AddSysCustomKey(key); 651 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); 652 } 653 654 ///
655 /// 出栈 656 /// 657 ///
658 ///
659 ///
660 public async Task
ListLeftPopAsync
(string key) 661 { 662 key = AddSysCustomKey(key); 663 var value = await Do(db => db.ListLeftPopAsync(key)); 664 return ConvertObj
(value); 665 } 666 667 ///
668 /// 获取集合中的数量 669 /// 670 ///
671 ///
672 public async Task
ListLengthAsync(string key) 673 { 674 key = AddSysCustomKey(key); 675 return await Do(redis => redis.ListLengthAsync(key)); 676 } 677 678 #endregion 异步方法 679 680 #endregion List 681 682 #region SortedSet 有序集合 683 684 #region 同步方法 685 686 ///
687 /// 添加 688 /// 689 ///
690 ///
691 ///
692 public bool SortedSetAdd
(string key, T value, double score) 693 { 694 key = AddSysCustomKey(key); 695 return Do(redis => redis.SortedSetAdd(key, ConvertJson
(value), score)); 696 } 697 698 ///
699 /// 删除 700 /// 701 ///
702 ///
703 public bool SortedSetRemove
(string key, T value) 704 { 705 key = AddSysCustomKey(key); 706 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 707 } 708 709 ///
710 /// 获取全部 711 /// 712 ///
713 ///
714 public List
SortedSetRangeByRank
(string key) 715 { 716 key = AddSysCustomKey(key); 717 return Do(redis => 718 { 719 var values = redis.SortedSetRangeByRank(key); 720 return ConvetList
(values); 721 }); 722 } 723 724 ///
725 /// 获取集合中的数量 726 /// 727 ///
728 ///
729 public long SortedSetLength(string key) 730 { 731 key = AddSysCustomKey(key); 732 return Do(redis => redis.SortedSetLength(key)); 733 } 734 735 #endregion 同步方法 736 737 #region 异步方法 738 739 ///
740 /// 添加 741 /// 742 ///
743 ///
744 ///
745 public async Task
SortedSetAddAsync
(string key, T value, double score) 746 { 747 key = AddSysCustomKey(key); 748 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson
(value), score)); 749 } 750 751 ///
752 /// 删除 753 /// 754 ///
755 ///
756 public async Task
SortedSetRemoveAsync
(string key, T value) 757 { 758 key = AddSysCustomKey(key); 759 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 760 } 761 762 ///
763 /// 获取全部 764 /// 765 ///
766 ///
767 public async Task
> SortedSetRangeByRankAsync
(string key) 768 { 769 key = AddSysCustomKey(key); 770 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 771 return ConvetList
(values); 772 } 773 774 ///
775 /// 获取集合中的数量 776 /// 777 ///
778 ///
779 public async Task
SortedSetLengthAsync(string key) 780 { 781 key = AddSysCustomKey(key); 782 return await Do(redis => redis.SortedSetLengthAsync(key)); 783 } 784 785 #endregion 异步方法 786 787 #endregion SortedSet 有序集合 788 789 #region key 790 791 ///
792 /// 删除单个key 793 /// 794 ///
redis key 795 ///
是否删除成功
796 public bool KeyDelete(string key) 797 { 798 key = AddSysCustomKey(key); 799 return Do(db => db.KeyDelete(key)); 800 } 801 802 ///
803 /// 删除多个key 804 /// 805 ///
rediskey 806 ///
成功删除的个数
807 public long KeyDelete(List
keys) 808 { 809 List
newKeys = keys.Select(AddSysCustomKey).ToList(); 810 return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys))); 811 } 812 813 ///
814 /// 判断key是否存储 815 /// 816 ///
redis key 817 ///
818 public bool KeyExists(string key) 819 { 820 key = AddSysCustomKey(key); 821 return Do(db => db.KeyExists(key)); 822 } 823 824 ///
825 /// 重新命名key 826 /// 827 ///
就的redis key 828 ///
新的redis key 829 ///
830 public bool KeyRename(string key, string newKey) 831 { 832 key = AddSysCustomKey(key); 833 return Do(db => db.KeyRename(key, newKey)); 834 } 835 836 ///
837 /// 设置Key的时间 838 /// 839 ///
redis key 840 ///
841 ///
842 public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) 843 { 844 key = AddSysCustomKey(key); 845 return Do(db => db.KeyExpire(key, expiry)); 846 } 847 848 #endregion key 849 850 #region 发布订阅 851 852 ///
853 /// Redis发布订阅 订阅 854 /// 855 ///
856 ///
857 public void Subscribe(string subChannel, Action
handler = null) 858 { 859 ISubscriber sub = _conn.GetSubscriber(); 860 sub.Subscribe(subChannel, (channel, message) => 861 { 862 if (handler == null) 863 { 864 Console.WriteLine(subChannel + " 订阅收到消息:" + message); 865 } 866 else 867 { 868 handler(channel, message); 869 } 870 }); 871 } 872 873 ///
874 /// Redis发布订阅 发布 875 /// 876 ///
877 ///
878 ///
879 ///
880 public long Publish
(string channel, T msg) 881 { 882 ISubscriber sub = _conn.GetSubscriber(); 883 return sub.Publish(channel, ConvertJson(msg)); 884 } 885 886 ///
887 /// Redis发布订阅 取消订阅 888 /// 889 ///
890 public void Unsubscribe(string channel) 891 { 892 ISubscriber sub = _conn.GetSubscriber(); 893 sub.Unsubscribe(channel); 894 } 895 896 ///
897 /// Redis发布订阅 取消全部订阅 898 /// 899 public void UnsubscribeAll() 900 { 901 ISubscriber sub = _conn.GetSubscriber(); 902 sub.UnsubscribeAll(); 903 } 904 905 #endregion 发布订阅 906 907 #region 其他 908 909 public ITransaction CreateTransaction() 910 { 911 return GetDatabase().CreateTransaction(); 912 } 913 914 public IDatabase GetDatabase() 915 { 916 return _conn.GetDatabase(DbNum); 917 } 918 919 public IServer GetServer(string hostAndPort) 920 { 921 return _conn.GetServer(hostAndPort); 922 } 923 924 ///
925 /// 设置前缀 926 /// 927 ///
928 public void SetSysCustomKey(string customKey) 929 { 930 CustomKey = customKey; 931 } 932 933 #endregion 其他 934 935 #region 辅助方法 936 937 private string AddSysCustomKey(string oldKey) 938 { 939 var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey; 940 return prefixKey + oldKey; 941 } 942 943 private T Do
(Func
func) 944 { 945 var database = _conn.GetDatabase(DbNum); 946 return func(database); 947 } 948 949 public string ConvertJson
(T value) 950 { 951 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); 952 return result; 953 } 954 955 public T ConvertObj
(RedisValue value) 956 { 957 return JsonConvert.DeserializeObject
(value); 958 } 959 960 private List
ConvetList
(RedisValue[] values) 961 { 962 List
result = new List
(); 963 foreach (var item in values) 964 { 965 var model = ConvertObj
(item); 966 result.Add(model); 967 } 968 return result; 969 } 970 971 private RedisKey[] ConvertRedisKeys(List
redisKeys) 972 { 973 return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); 974 } 975 976 #endregion 辅助方法 977 978 #region 批量操作 979 980 #region 批量写Key-Value 981 ///
982 /// 批量写Key-Value 983 /// 984 ///
985 ///
986 public bool StringWriteBatch(List
> keyValues) 987 { 988 bool result = false; 989 try 990 { 991 var db = _conn.GetDatabase(); 992 var batch = db.CreateBatch(); 993 foreach (var item in keyValues) 994 { 995 batch.StringSetAsync(item.Key, item.Value); 996 } 997 batch.Execute(); 998 result = true; 999 }1000 catch1001 {1002 }1003 return result;1004 }1005 #endregion1006 1007 #region 批量读Key-Value1008 ///
1009 /// 批量读Key-Value1010 /// 1011 ///
1012 ///
1013 ///
1014 public List
StringReadBatch
(List
lstKey)1015 {1016 List
> valueList = new List
>();1017 List
lstResult = new List
();1018 try1019 {1020 var db = _conn.GetDatabase();1021 var batch = db.CreateBatch();1022 foreach (var item in lstKey)1023 {1024 Task
value = batch.StringGetAsync(item);1025 valueList.Add(value);1026 }1027 batch.Execute();1028 1029 foreach (var item in valueList)1030 {1031 T t = ConvertObj
(item.Result);1032 lstResult.Add(t);1033 }1034 }1035 catch1036 {1037 }1038 return lstResult;1039 }1040 1041 ///
1042 /// 批量读操作,返回DataSe集合1043 /// 1044 ///
1045 ///
1046 public DataSet StringReadBatch(List
lstKey)1047 {1048 if (lstKey == null || lstKey.Count < 1) return null;1049 List
> valueList = new List
>();1050 DataSet ds = new DataSet();1051 try1052 {1053 var db = _conn.GetDatabase();1054 var batch = db.CreateBatch();1055 foreach (var item in lstKey)1056 {1057 Task
value = batch.StringGetAsync(item);1058 valueList.Add(value);1059 }1060 batch.Execute();1061 1062 foreach (var item in valueList)1063 {1064 DataTable t = ConvertObj
(item.Result);1065 ds.Tables.Add(t);1066 }1067 }1068 catch1069 {1070 }1071 return ds;1072 }1073 #endregion1074 1075 #region 批量写Hash1076 ///
1077 /// 批量写Hash1078 /// 1079 ///
1080 ///
1081 public bool HashWriteBatch(List
> keyValues)1082 {1083 bool result = false;1084 try1085 {1086 var db = _conn.GetDatabase();1087 var batch = db.CreateBatch();1088 foreach (var item in keyValues)1089 {1090 batch.HashSetAsync(item.Key, item.Value);1091 }1092 batch.Execute();1093 result = true;1094 }1095 catch1096 {1097 }1098 return result;1099 }1100 #endregion1101 1102 #region 批量读Hash1103 ///
1104 /// 批量读Hash1105 /// 1106 ///
hash键和field1107 ///
1108 public List
HashReadBatch
(List
> keyFields)1109 {1110 List
> valueList = new List
>();1111 List
lstResult = new List
();1112 try1113 {1114 var db = _conn.GetDatabase();1115 var batch = db.CreateBatch();1116 foreach (var item in keyFields)1117 {1118 Task
value = batch.HashGetAsync(item.Key, item.Value);1119 valueList.Add(value);1120 }1121 batch.Execute();1122 1123 foreach (var item in valueList)1124 {1125 if (item.Result == null) continue;1126 foreach (var redisValue in item.Result)1127 {1128 T t = ConvertObj
(redisValue);1129 lstResult.Add(t);1130 }1131 }1132 }1133 catch1134 {1135 }1136 return lstResult;1137 }1138 #endregion1139 1140 #endregion

3)单例模式

1 ///   2     /// ConnectionMultiplexer对象管理帮助类  3     ///   4     public static class RedisConnectionHelp  5     {  6         //系统自定义Key前缀  7         public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? "";  8   9         //"127.0.0.1:6379,allowadmin=true 10         private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 11  12         private static readonly object Locker = new object(); 13         private static ConnectionMultiplexer _instance; 14         private static readonly ConcurrentDictionary
ConnectionCache = new ConcurrentDictionary
(); 15 16 ///
17 /// 单例获取 18 /// 19 public static ConnectionMultiplexer Instance 20 { 21 get 22 { 23 if (_instance == null) 24 { 25 lock (Locker) 26 { 27 if (_instance == null || !_instance.IsConnected) 28 { 29 _instance = GetManager(); 30 } 31 } 32 } 33 return _instance; 34 } 35 } 36 37 ///
38 /// 缓存获取 39 /// 40 ///
41 ///
42 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 43 { 44 if (!ConnectionCache.ContainsKey(connectionString)) 45 { 46 ConnectionCache[connectionString] = GetManager(connectionString); 47 } 48 return ConnectionCache[connectionString]; 49 } 50 51 private static ConnectionMultiplexer GetManager(string connectionString = null) 52 { 53 connectionString = connectionString ?? RedisConnectionString; 54 var connect = ConnectionMultiplexer.Connect(connectionString); 55 56 //注册如下事件 57 connect.ConnectionFailed += MuxerConnectionFailed; 58 connect.ConnectionRestored += MuxerConnectionRestored; 59 connect.ErrorMessage += MuxerErrorMessage; 60 connect.ConfigurationChanged += MuxerConfigurationChanged; 61 connect.HashSlotMoved += MuxerHashSlotMoved; 62 connect.InternalError += MuxerInternalError; 63 64 return connect; 65 } 66 67 #region 事件 68 69 ///
70 /// 配置更改时 71 /// 72 ///
73 ///
74 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) 75 { 76 Console.WriteLine("Configuration changed: " + e.EndPoint); 77 } 78 79 ///
80 /// 发生错误时 81 /// 82 ///
83 ///
84 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) 85 { 86 Console.WriteLine("ErrorMessage: " + e.Message); 87 } 88 89 ///
90 /// 重新建立连接之前的错误 91 /// 92 ///
93 ///
94 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) 95 { 96 Console.WriteLine("ConnectionRestored: " + e.EndPoint); 97 } 98 99 ///
100 /// 连接失败 , 如果重新连接成功你将不会收到这个通知101 /// 102 ///
103 ///
104 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)105 {106 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));107 }108 109 ///
110 /// 更改集群111 /// 112 ///
113 ///
114 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)115 {116 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);117 }118 119 ///
120 /// redis类库错误121 /// 122 ///
123 ///
124 private static void MuxerInternalError(object sender, InternalErrorEventArgs e)125 {126 Console.WriteLine("InternalError:Message" + e.Exception.Message);127 }128 129 #endregion 事件130 }

4)app.config中增加redis连接字符串

 

转载地址:http://npnex.baihongyu.com/

你可能感兴趣的文章
golang+es 爬取网易云音乐评论
查看>>
Math Constants
查看>>
Ajax.BeginForm的异步提交数据 简介
查看>>
Oracle 11g不能导出空表的三种解决方法
查看>>
Wordpress 文章添加副标题
查看>>
21 段实用便捷的 PHP 代码
查看>>
包子凑数
查看>>
CocosStudio文件解析工具CsdAnalysis
查看>>
python 网络通信编程之tcp套接字socket
查看>>
Sql语句批量更新数据(多表关联)
查看>>
设置密码到期的天数
查看>>
Matlab M文件“程序块”注释方法
查看>>
当当网首页——html代码
查看>>
使用JDBCTemplate实现与Spring结合,方法公用 ——共用实现类(BaseImpl)
查看>>
asp.net mvc 实战化项目之三板斧
查看>>
使用stream类型的Result实现Ajax
查看>>
2012,C++,学,还是不学?
查看>>
HDOJ1002
查看>>
自己重新编译VLFeat
查看>>
Scrapy简介
查看>>