C# 读写redis C#读写实时数据库


引用: https://www.cnblogs.com/dathlin/p/9998013.html

本文将使用一个gitHub开源的组件技术来读写redis数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作

github地址:https://github.com/dathlin/HslCommunication      fork      star                 如果喜欢可以star或是fork,还可以打赏支持。

官网地址:http://www.hslcommunication.cn/    

联系作者及加群方式(激活码在群里发放):http://www.hslcommunication.cn/Cooperation 

 

 

Redis是什么?


 这个是一个实时的数据库技术,主要采用键值操作来存储数据的。官网是 https://redis.io/ ,官方的解释为(摘自百度百科):

 

redis是一个key-value 存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list( 链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些 数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了 memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。  [1] 
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的官网地址,非常好记,是redis.io。(特意查了一下,域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)
目前,Vmware在资助着redis项目的开发和维护。

 

安装redis服务器


我们在使用前需要安装服务器,一般的windows的服务器来自于微软的项目:

https://github.com/MicrosoftArchive/redis/releases

虽然微软的项目只更新到了 redis3.2 版本。但是已经足够我们日常的使用了。

 

安装完成后,会自动的启动服务器。我们可以打开cmd来测试

 

 

服务器搭好后就可以使用C#来操作了。

再次随便聊聊,C#有个还可以的redis类库叫StackExchange.Redis

https://github.com/StackExchange/StackExchange.Redis

但是这个类库呢,总有些莫名其妙的问题,尤其是超时问题,始终没有得到很好的解决,所以我集成实现了redis的基本操作,给大家一个更多的选择。支持.net framework和.net standard

 

当你的程序实现了redis之后,程序架构变成了:

此处的redis相当于高速的数据缓存,可以部署在服务器的电脑上,可以部署在云端等等,任意其他的电脑上面。

接下来演示使用HSL来进行操作

 

从NUGET安装


 

 

1
Install-Package HslCommunication

  

 

关于两种模式


在PLC端,包括三菱,西门子,欧姆龙,AB以及Modbus Tcp客户端的访问器上,都支持两种模式,短连接模式和长连接模式,现在就来解释下什么原理。

短连接:每次读写都是一个单独的请求,请求完毕也就关闭了,如果服务器的端口仅仅支持单连接,那么关闭后这个端口可以被其他连接复用,但是在频繁的网络请求下,容易发生异常,会有其他的请求不成功,尤其是多线程的情况下。

长连接:创建一个公用的连接通道,所有的读写请求都利用这个通道来完成,这样的话,读写性能更快速,即时多线程调用也不会影响,内部有同步机制。如果服务器的端口仅仅支持单连接,那么这个端口就被占用了,比如三菱的端口机制,西门子的Modbus tcp端口机制也是这样的。以下代码默认使用长连接,性能更高,还支持多线程同步。

在短连接的模式下,每次请求都是单独的访问,所以没有重连的困扰,在长连接的模式下,如果本次请求失败了,在下次请求的时候,会自动重新连接服务器,直到请求成功为止。另外,尽量所有的读写都对结果的成功进行判断。

 

 

DEMO示例:


 

下面的一个项目是这个组件的访问测试项目,您可以进行初步的访问的测试。该项目位于本篇文章开始处的Gitbub源代码里面的

DEMO的开源地址:https://github.com/dathlin/HslRedisDesktop

 

 

 

 

 

可以用来浏览你的redis到底有什么数据,以及这个数据是什么,初步支持了  string,list,hash 数据类型。

当你写入的key名字带有:(英文状态)时。这个浏览器还会对数据进行分类整理、

 

关于redis指令


 

http://doc.redisfans.com/index.html

 

 

原生的指令有很多,这个库里也是支持了大部分的操作,如果你需要的功能还没有支持,比如 获取一个键的数据信息, 将指令参数按照空格输入进去就行

1
2
3
4
5
6
7
8
9
10
11
12
13
private  void  button16_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ReadCustomer( "GET A"  );
     if  (read.IsSuccess)
     {
         // read.Content 就是从服务器返回的数据 例如为 $2\r\n11\r\n  需要自己提炼真实的数据
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  

 

 

 下面列举一些示例

 

 

 

简单使用


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Threading.Tasks;
using  System.Windows.Forms;
using  HslCommunication.Enthernet.Redis;
using  HslCommunication;
 
namespace  WindowsFormsApp3
{
     public  partial  class  Form1 : Form
     {
         public  Form1( )
         {
             InitializeComponent( );
         }
 
 
         private  RedisClient redisClient =  new  RedisClient(  "127.0.0.1" , 6379,  ""  );
         private  void  button1_Click(  object  sender, EventArgs e )
         {
             OperateResult< string > read = redisClient.ReadKey(  "a"  );
             if  (read.IsSuccess)
             {
                 MessageBox.Show( read.Content );
             }
             else
             {
                 MessageBox.Show( read.Message );
             }
         }
     }
}

  

结果如下:

 

显示的值就是我们之前写入的操作,主要,redis区分大小写,你读  A  和读 a 是不一样的。

上述的代码已经进行了严格的验证,上面情况会读取失败呢?网络异常或是 a 不存在

 

我们来看看写入键值:

1
2
3
4
private  void  button2_Click(  object  sender, EventArgs e )
{
     OperateResult write = redisClient.WriteKey(  "a" "abcde"  );
}

 

上述就没有对写入成功与否进行验证,只要是网络正常基本都是成功的。

写完后我们再读取一次:

 

 

 

如果想写入一个有生命周期的key,比如100s后自动消失的key

1
2
3
4
private  void  button3_Click(  object  sender, EventArgs e )
{
     OperateResult write = redisClient.WriteExpireKey(  "b" "abcde" , 100 );
}

 

这样就写入了一个带生命周期的key了。

 

批量读写


 

 如果想要一次性写入或是读取很多键值:

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button4_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ReadKey(  new  string [] {  "a" "b"  } );
     if  (read.IsSuccess)
     {
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

写入的操作如下:

1
2
3
4
private  void  button5_Click(  object  sender, EventArgs e )
{
     redisClient.WriteKey(  new  string [] {  "a" "b"  },  new  string [] {  "abcde" "ihsdasd"  } );
}

此处省略了对写入结果的验证,为了安全起见,你应该添加。

 

获取旧值,并设置一个新的值进去

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button6_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ReadAndWriteKey(  "a" "aaaaaa"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  

 递增递减操作。


 

 这个基本功能也是很常见的、

我们先写 BB 为 0

 

 然后我们再给这个值加1,并返回1的操作。

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button7_Click(  object  sender, EventArgs e )
{
     OperateResult< int > read = redisClient.IncrementKey(  "BB"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show(  "Value:"  + read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

同理也支持减一操作,增加指定的数据操作,减去指定的数据操作。

 

 

 

 

列表操作


 

redis也支持存储数组数据信息

我们创建一个数组,并往里面塞东西,当然支持从数组的左侧塞,也支持从右侧塞,下面就是左侧的例子

1
2
3
4
private  void  button8_Click(  object  sender, EventArgs e )
{
     redisClient.ListLeftPush(  "C" "123"  );
}

这样就创建了一个数组,数组数据的读取,并不是get了,而是变成了 LRANGE 0 -1 代表读取整个的数组

 

用代码来读取就是

1
2
3
4
5
6
7
8
9
10
11
12
13
private  void  button9_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ListRange(  "C" , 0, -1 );
     if  (read.IsSuccess)
     {
         // 列表变成了一个数组信息
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

 

当然,当你的数组很大时。比如1000个长度时,你可以读取中间任意个数组。

 

获取数组长度


 

 当你不知道一个数组的长度,不想在读取所有的数组信息的情况下,读取到长度

1
2
3
4
private  void  button10_Click(  object  sender, EventArgs e )
{
     int  length = redisClient.GetListLength(  "C"  ).Content;  // 此处就是1
}

 

获取指定索引的数据


 

1
2
3
4
private  void  button11_Click(  object  sender, EventArgs e )
{
     string  read = redisClient.ReadListByIndex(  "C" , 0 ).Content;
}

 

注意,当C不是list时,会引发错误。  

 

 

修剪列表信息


当数组过长时,我们可以修剪数组来达到收缩的目的

1
2
3
4
private  void  button12_Click(  object  sender, EventArgs e )
{
     redisClient.ListTrim(  "C" , 0, 9 ); // 10个长度,保留0-9索引的数据
}

  

 

返回并移除开始处的列表


 

 

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button13_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ListLeftPop(  "C"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  移除并返回测试的也是可以的。

 

 

 

哈希值读写


 

哈希值的意思是一个键的值是由多个键值组成的

1
2
3
4
5
6
private  void  button14_Click(  object  sender, EventArgs e )
{
     redisClient.WriteHashKey(  "D" "A" "1"  );
     redisClient.WriteHashKey(  "D" "B" "2"  );
     redisClient.WriteHashKey(  "D" "C" "3"  );
}

  

相当于是键 D 的域 A 写入1, B写入2,C写入3

你一次可以读取所有的C的域集合,或是值集合,或是域+值集合,下面演示了一个示例,读取域+值集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private  void  button15_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ReadHashKeyAll(  "C"  );
     if  (read.IsSuccess)
     {
         // 列表变成了一个域+值信息
         // A
         // 1
         // B
         // 2
         // C
         // 3
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM