Redis学习笔记:Redis在C#中的使用
程序员文章站
2022-03-10 18:37:50
1、新建一个WinForm窗体,命名为Main: 2、在NuGet中安装StackExchange.Redis。 3、添加一个类,命名为RedisHelper。 public static class RedisHelper { private static string Constr = ""; ......
1、新建一个winform窗体,命名为main:
2、在nuget中安装stackexchange.redis。
3、添加一个类,命名为redishelper。
public static class redishelper { private static string constr = ""; private static readonly object _locker = new object(); private static connectionmultiplexer _instance = null; /// <summary> /// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 connectionmultiplexer 断开连接,便可以初始化新的连接实例。 /// </summary> public static connectionmultiplexer instance { get { if (constr.length == 0) { throw new exception("连接字符串未设置!"); } if (_instance == null) { lock (_locker) { if (_instance == null || !_instance.isconnected) { _instance = connectionmultiplexer.connect(constr); } } } //注册如下事件 _instance.connectionfailed += muxerconnectionfailed; _instance.connectionrestored += muxerconnectionrestored; _instance.errormessage += muxererrormessage; _instance.configurationchanged += muxerconfigurationchanged; _instance.hashslotmoved += muxerhashslotmoved; _instance.internalerror += muxerinternalerror; return _instance; } } static redishelper() { } public static void setcon(string config) { constr = config; } public static idatabase getdatabase() { return instance.getdatabase(); } /// <summary> /// 这里的 mergekey 用来拼接 key 的前缀,具体不同的业务模块使用不同的前缀。 /// </summary> /// <param name="key"></param> /// <returns></returns> private static string mergekey(string key) { return key; //return basesysteminfo.systemcode + key; } /// <summary> /// 根据key获取缓存对象 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="key"></param> /// <returns></returns> public static t get<t>(string key) { key = mergekey(key); return deserialize<t>(getdatabase().stringget(key)); } /// <summary> /// 根据key获取缓存对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public static object get(string key) { key = mergekey(key); return deserialize<object>(getdatabase().stringget(key)); } /// <summary> /// 设置缓存 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expireminutes"></param> public static void set(string key, object value, int expireminutes = 0) { key = mergekey(key); if (expireminutes > 0) { getdatabase().stringset(key, serialize(value), timespan.fromminutes(expireminutes)); } else { getdatabase().stringset(key, serialize(value)); } } /// <summary> /// 判断在缓存中是否存在该key的缓存数据 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool exists(string key) { key = mergekey(key); return getdatabase().keyexists(key); //可直接调用 } /// <summary> /// 移除指定key的缓存 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool remove(string key) { key = mergekey(key); return getdatabase().keydelete(key); } /// <summary> /// 异步设置 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public static async task setasync(string key, object value) { key = mergekey(key); await getdatabase().stringsetasync(key, serialize(value)); } /// <summary> /// 根据key获取缓存对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public static async task<object> getasync(string key) { key = mergekey(key); object value = await getdatabase().stringgetasync(key); return value; } /// <summary> /// 实现递增 /// </summary> /// <param name="key"></param> /// <returns></returns> public static long increment(string key) { key = mergekey(key); //三种命令模式 //sync,同步模式会直接阻塞调用者,但是显然不会阻塞其他线程。 //async,异步模式直接走的是task模型。 //fire - and - forget,就是发送命令,然后完全不关心最终什么时候完成命令操作。 //即发即弃:通过配置 commandflags 来实现即发即弃功能,在该实例中该方法会立即返回,如果是string则返回null 如果是int则返回0.这个操作将会继续在后台运行,一个典型的用法页面计数器的实现: return getdatabase().stringincrement(key, flags: commandflags.fireandforget); } /// <summary> /// 实现递减 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public static long decrement(string key, string value) { key = mergekey(key); return getdatabase().hashdecrement(key, value, flags: commandflags.fireandforget); } /// <summary> /// 序列化对象 /// </summary> /// <param name="o"></param> /// <returns></returns> private 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> private 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.safelogmessage("configuration changed: " + e.endpoint); } /// <summary> /// 发生错误时 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void muxererrormessage(object sender, rediserroreventargs e) { //loghelper.safelogmessage("errormessage: " + e.message); } /// <summary> /// 重新建立连接之前的错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void muxerconnectionrestored(object sender, connectionfailedeventargs e) { //loghelper.safelogmessage("connectionrestored: " + e.endpoint); } /// <summary> /// 连接失败,如果重新连接成功你将不会收到这个通知。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void muxerconnectionfailed(object sender, connectionfailedeventargs e) { //loghelper.safelogmessage("重新连接:endpoint failed: " + e.endpoint + ", " + e.failuretype +(e.exception == null ? "" : (", " + e.exception.message))); } /// <summary> /// 更改集群 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void muxerhashslotmoved(object sender, hashslotmovedeventargs e) { //loghelper.safelogmessage("hashslotmoved:newendpoint" + e.newendpoint + ", oldendpoint" + e.oldendpoint); } /// <summary> /// redis类库错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void muxerinternalerror(object sender, internalerroreventargs e) { //loghelper.safelogmessage("internalerror:message" + e.exception.message); } //场景不一样,选择的模式便会不一样,大家可以按照自己系统架构情况合理选择长连接还是lazy。 //建立连接后,通过调用connectionmultiplexer.getdatabase 方法返回对 redis cache 数据库的引用。从 getdatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。 /// <summary> /// 使用的是lazy,在真正需要连接时创建连接。 /// 延迟加载技术 /// 微软azure中的配置 连接模板 /// </summary> //private static lazy<connectionmultiplexer> lazyconnection = new lazy<connectionmultiplexer>(() => //{ // //var options = configurationoptions.parse(constr); // ////options.clientname = getappname(); // only known at runtime // //options.allowadmin = true; // //return connectionmultiplexer.connect(options); // connectionmultiplexer muxer = connectionmultiplexer.connect(coonstr); // muxer.connectionfailed += muxerconnectionfailed; // muxer.connectionrestored += muxerconnectionrestored; // muxer.errormessage += muxererrormessage; // muxer.configurationchanged += muxerconfigurationchanged; // muxer.hashslotmoved += muxerhashslotmoved; // muxer.internalerror += muxerinternalerror; // return muxer; //}); #region 当作消息代理中间件使用 一般使用更专业的消息队列来处理这种业务场景 /// <summary> /// 当作消息代理中间件使用 /// 消息组建中,重要的概念便是生产者、消费者、消息中间件。 /// </summary> /// <param name="channel"></param> /// <param name="message"></param> /// <returns></returns> public static long publish(string channel, string message) { isubscriber sub = instance.getsubscriber(); //return sub.publish("messages", "hello"); return sub.publish(channel, message); } /// <summary> /// 在消费者端得到该消息并输出 /// </summary> /// <param name="channelfrom"></param> /// <returns></returns> public static void subscribe(string channelfrom) { isubscriber sub = instance.getsubscriber(); sub.subscribe(channelfrom, (channel, message) => { console.writeline(message); }); } #endregion /// <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; } }
4、main窗体代码:
public partial class main : form { public main() { initializecomponent(); try { string redisconf = "127.0.0.1:6379,password=12345,defaultdatabase=0"; redishelper.setcon(redisconf); } catch (exception ex) { messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information); } } /// <summary> /// 设置 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_click(object sender, eventargs e) { if (string.isnullorempty(textbox1.text)) { textbox4.text = "请填写键"; return; } if (string.isnullorempty(textbox2.text)) { textbox4.text = "请填写值"; return; } if (string.isnullorempty(textbox3.text)) { textbox4.text = "请填写过期时间"; return; } //键、值、过期时间 redishelper.set(textbox1.text, textbox2.text, int.parse(textbox3.text)); textbox4.text = "添加成功"; } /// <summary> /// 删除 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_click(object sender, eventargs e) { if (!string.isnullorempty(textbox1.text)) { if (redishelper.exists(textbox1.text)) { redishelper.remove(textbox1.text).tostring(); textbox4.text = "删除成功"; } else { textbox4.text = "已过期或不存在"; } } else { textbox4.text = "请填写键"; } } /// <summary> /// 获取 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_click(object sender, eventargs e) { if (!string.isnullorempty(textbox1.text)) { if (redishelper.exists(textbox1.text)) { textbox4.text = redishelper.get(textbox1.text).tostring(); } else { textbox4.text = "已过期或不存在"; } } else { textbox4.text = "请填写键"; } } /// <summary> /// 分钟数--非backspace键或数字时处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void textbox3_keypress(object sender, keypresseventargs e) { if (e.keychar != 8 && !char.isdigit(e.keychar)) { e.handled = true; } } }
5、运行结果:
参考自:
上一篇: Java 操作Redis
下一篇: java实现身份证识别