首页 > 数据库 >C# redis操作(StackExchange.Redis )

C# redis操作(StackExchange.Redis )

时间:2023-10-30 11:01:52浏览次数:36  
标签:database C# redis System new using StackExchange chanel

参考:https://www.cnblogs.com/wzh2010/p/17205387.html

参考:https://www.runoob.com/redis/redis-keys.html

测试redis, 使用StackExchange.Redis 的api, 实现发布/订阅,  存放值,  分布式锁, 排序

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using StackExchange.Redis;

namespace RedisTest
{
    struct Msg
    {
        public string chanel;
        public byte[] msg;

        public Msg(string chanel, byte[] msg)
        {
            this.chanel = chanel;
            this.msg = msg;
        }
    }

    public partial class Form1 : Form
    {
        ConnectionMultiplexer redisClient = ConnectionMultiplexer.Connect("127.0.0.1:6359,allowadmin=true,password=12345,keepAlive=180");
        ISubscriber m_subscriber;
        IDatabase m_database;
        Queue<Msg> m_msgQueue = new Queue<Msg>();
        bool m_Closed = false;
        private ManualResetEvent m_ManualResetEvent = new ManualResetEvent(false);

        public Form1()
        {
            InitializeComponent();
        }

        private void DoJob()
        {
            while (true)
            {
                if (m_msgQueue.Count == 0)
                {
                    m_ManualResetEvent.WaitOne();
                    if(m_Closed)
                    {
                        break;
                    }
                }
                else
                {
                    Action action = () =>
                    {
                        var msg = m_msgQueue.Dequeue();
                        string str = UTF8Encoding.UTF8.GetString(msg.msg);
                        this.txtResult.Text += "chanel:"  + msg.chanel + "," + str + "\r\n";
                    };
                    this.txtResult.Invoke(action);
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread thread = new Thread(DoJob);
            thread.Start();
            
            //127.0.0.1:6379,allowadmin=true,password=12345,keepAlive=180
            // 设置订阅
            m_subscriber = redisClient.GetSubscriber();
            // 设置数据库
            m_database = redisClient.GetDatabase(0);

            m_subscriber.Subscribe("testchanel", (chanel, message)=>{
                m_msgQueue.Enqueue(new Msg(chanel, message));
                m_ManualResetEvent.Set();
            });

            /*
            m_subscriber.Subscribe("bb", (chanel, message) => {
                // lamda表达式转delegate
                Action action = () =>
                {
                    this.txtResult.Text += "chanel:" + chanel + "," + message + "\r\n";
                };
                this.txtResult.Invoke(action);
            });
            */
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string str = this.txtSend.Text + DateTime.Now.Ticks;
            m_subscriber.Publish("testchanel", str);
            /*
            byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(str);
            m_subscriber.Publish("bb", bytes);
            */
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            m_Closed = true;
            m_ManualResetEvent.Set();
        }

        private void btnSaveLoad_Click(object sender, EventArgs e)
        {
            // 参考:https://www.cnblogs.com/wzh2010/p/17205387.html
            // 参考:https://www.runoob.com/redis/redis-keys.html
            // 这个可以用来做分布式锁, 设置某个键, 并加超时时间, 并且可以设置只有不存在时才处理
            // SETNX 是 set if not exists 的缩写,当且仅当 key 不存在时,则设置 value 给这个key。若给定的 key 已经存在,则 SETNX 不做任何动作。
            // 命令的返回值说明:1:说明该进程获得锁,将 key 的值设为 value 0:说明其他进程已经获得了锁,进程不能进入临界区。

            // SET lock.user_063105015 1 NX PX 60000
            // NX:就是Not Exist,表示只有用户编号为 063105015 不存在的时候才可以 SET 成功,并且只有单个线程可以获取锁;
            // PX 60000:表示对这个锁设置一个60s的过期时间。
            bool ret = m_database.StringSet("mykeystring", 33, new TimeSpan(0, 0, 5), When.NotExists);

            m_database.SetAdd("myset", "set1");
            m_database.SetAdd("myset", "set2");
            m_database.ListRightPush("mylist", 1);
            m_database.ListRightPush("mylist", 2);

            // 可以使用StringGetSet, 取出旧值, 设置新值
            // 对应redis, GetSet命令, 可以使用这个来实现 分布式锁, 返回原来的值, 并且设置新的值
            // 下面的例子, 可以在拿的值判断拿到的值是否为1, 如果为1, 则说明被其它人设置了, 如果不是1, 则说明没被其它人操作,
            // 操作完删除key, 或更新成其它值
            var val = m_database.StringGetSet("myGetSetKey", 1);
            // 这个是给key加个超时, 防止程序异常中断, 死锁 对应redis EXPIRE key seconds, expire key 时间戳

            // GETEX命令同样也是Redis 6.2.0中新增的命令,它用于获取指定键值对的值,并设置或移除该键值对的过期时间。
            // 这儿测试时用的3.几的reids, 下面执行不了
            // 
            //var val2 = m_database.StringGetSetExpiry("myGetSetKey", new TimeSpan(0, 0, 3));
            
            m_database.StringAppend("mystring", "str1");
            m_database.StringAppend("mystring", "str2");
            var entery1 = new HashEntry("a", 1);
            var entery2 = new HashEntry("b", 2);
            m_database.HashSet("myhashkey", new HashEntry[] { entery1, entery2 });

            //redis zset排序
            m_database.SortedSetAdd("myzset", "一", 8);
            m_database.SortedSetAdd("myzset", "二", 9);
            m_database.SortedSetAdd("myzset", "三", 7);
            long? rank = m_database.SortedSetRank("myzset", "二"); //这儿返回0, 第一名
        }
    }
}

 下载测试代码

标签:database,C#,redis,System,new,using,StackExchange,chanel
From: https://www.cnblogs.com/barrysgy/p/17797280.html

相关文章

  • ArmSom--I2C开发指南
    1.简介RK3588从入门到精通本⽂介绍在rockchip平台下如何配置i2c接口的方法并且添加调试验证i2c外设的例子开发板:ArmSoM-W3Kernel:5.10.160OS:Debian112.i2c接口概述i2c总线控制器通过串行数据(SDA)线和串行时钟(SCL)线在连接到总线的器件间传递信息。i2c总线一些......
  • 在CentOS7上更改端口号时报错:Job for sshd.service failed because the control proce
    1、问题描述在在CentOS7×上更改端口号时报错:“Jobforsshd.servicefailedbecausethecontrolprocessexitedwitherrorcode.See‘systemclstatus&sshdservice"andfournalctixe'fordetails.”2、修改ssh端口号的方法sudovim/etclssh/sshd_config将“#Port......
  • tcp连接断开的四次挥手。
    1.c端将FIN置1,向s端发送请求断开序列号例如是m;2.s端接收到后向c端发送应答将m+1;3.当s端完成数据交换也不需要通信的时候,向c端发送序列号n请求断开;4.c端将n+1后发送应答给s端。 ......
  • CPU 100%问题排查
    引用:https://blog.csdn.net/qq_37515544/article/details/123921604https://blog.csdn.net/yujing1314/article/details/114524668 一、定位哪个程序占用的CPU较高linux命令:top    二、jstack使用2.1栈信息输出命令格式:jstackpid>文件信息eg:jstack5115>a.tx......
  • ChatGPT回答
    关于<parent>标签<parent><groupId>com.holdtime</groupId><artifactId>jpms3-platform</artifactId><version>1.6.6.3</version></parent>Maven的项目配置文件pom.xml中的<parent>元素,用于指定该项目的父级项目。......
  • ArmSom--I2C开发指南
    1.简介RK3588从入门到精通本⽂介绍在rockchip平台下如何配置i2c接口的方法并且添加调试验证i2c外设的例子开发板:ArmSoM-W3Kernel:5.10.160OS:Debian11  2.i2c接口概述i2c总线控制器通过串行数据(SDA)线和串行时钟(SCL)线在连接到总线的器件间传递信息。i2c......
  • tcp三次握手。
    1.c端将SYN置一,然后向s端发送一串序列号例如x,这是第一次握手;2.s端接收到后发送x+1应答,同时发送一个自己的序列号y,这是第二次握手;3.c端收到应答后,将y+1发送给s端,完成第三次握手。注:SYN:同步的缩写,意思是双方保持步调一致。ACK:  确认字符。......
  • LeetCode每日算法2—两数相加
    题目描述给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字0之外,这两个数都不会以0开头。示例输入:(2......
  • 区分association和collection
    1.关联- association 【多对一】2.集合-collection【一对多】3.javaType&ofType(1)JavaType用来指定实体类中的类型(2)ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型多对一实体类:按查询嵌套,子查询 按结果嵌套,连表查询 一对多实体类......
  • Could not load host key: /etc/ssh/ssh_host_rsaxxx
    /usr/sbin/sshd错误提示:Couldnot loadhostkey:/etc/ssh/ssh_host_rsa_keyCouldnot loadhostkey:/etc/ssh/ssh_host_ecdsa_keyCouldnot loadhostkey:/etc/ssh/ssh_host_ed25519_keysshd:nohostkeysavailable --exiting. 解决方法: ssh-keygen......