[转]C# 连接池开发,多连接高效应用开发,多连接自动维护管理

 

本文将使用一个Github开源的组件库技术来实现连接池的操作,应用于一些情况下的频繁的网络连接操作。

github地址:https://github.com/dathlin/HslCommunication 如果喜欢可以star或是fork,还可以打赏支持,打赏请认准源代码项目。

本项目目前支持C#语言和java语言,C#语言的功能比较齐全,java版本的库还在开发及完善中。

nuget地址:https://www.nuget.org/packages/HslCommunication/       nuget     下载

github地址:https://github.com/dathlin/HslCommunication      fork      star                   

  如果喜欢可以star或是fork,还可以打赏支持。

 

组件的完整信息和API介绍参照:http://www.cnblogs.com/dathlin/p/7703805.html   组件的使用限制,更新日志,都在该页面里面。

 

为什么需要连接池


首先需要解决这个问题,我们为什么需要连接池,终极目的是是为了高效的数据访问,但并不是所有情况都需要进行连接池搭建的,举几个🌰吧

 

案例一:你有个后台线程每隔1s钟在读取PLC的数据,你和PLC的交互都在这个线程里面,那么完全是不需要进行连接池的。

案例二:你会在程序的多个线程(包括线程池里面)进行和PLC进行数据交互,频繁的读写操作,如果共用一个连接的性能达不到要求怎么办(通常在无线网络下,一次数据交互在30ms-100ms之间,网络波动较大)?,如果每次操作都创建连接,操作结束后关闭,这样也可以达到功能,只是损耗性能比较严重,无论是对PLC还是本机,通讯的效率也不是很理想,因为每次操作都是重新连接和关闭,这里的PLC实际上可以替换成数据库,Redis,其他任何的数据通信。

 

什么时候不能连接池


 

并不是所有的情况都可以使用连接池的,有个巨大的限制,如果服务器不支持多连接就很麻烦,比如说三菱PLC的服务器的端口,当然,一般的数据库,Redis,特殊的服务器都是支持。当然,有些特殊的服务器,支持的连接数是有上限的,没事,本组件也可以配置上限的连接数。

 

特性支持


 本功能类的设计之初,就是兼顾灵活性,为了支持其他所有的不同类型的数据通信,采用接口+泛型来实现,先构建一个通信封装类,再进行创建一个连接池管理器,再调用使用。

  1. 支持配置最大的连接数
  2. 支持设置连接过期时间
  3. 支持任意的其他类型的连接对象变成连接池

 

 

实战示例


 

此处举例访问西门子的PLC,所以第一步是创建一个连接的封装类,除了实现接口外,还需要定义真实的连接对象。

 
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class SiemensConnector : HslCommunication.Algorithms.ConnectPool.IConnector
{
    #region 构造方法
 
    public SiemensConnector( string ipAddress )
    {
        siemens = new HslCommunication.Profinet.Siemens.SiemensS7Net( HslCommunication.Profinet.Siemens.SiemensPLCS.S1200, ipAddress );
    }
 
    #endregion
 
    #region IConnector 实现
 
 
    /// <summary>
    /// 指示当前的连接是否在使用用
    /// </summary>
    public bool IsConnectUsing { get; set; }
 
 
    /// <summary>
    /// 唯一的GUID码
    /// </summary>
    public string GuidToken { get; set; }
 
 
    /// <summary>
    /// 最新一次使用的时间
    /// </summary>
    public DateTime LastUseTime { get; set; }
 
 
    /// <summary>
    /// 打开连接
    /// </summary>
    public void Open( )
    {
        // 设置常连接。如果是Redis,可以连接服务器,数据库也是一样
        siemens.ConnectServer( );
    }
 
 
    /// <summary>
    /// 关闭并释放
    /// </summary>
    public void Close( )
    {
        // 关闭连接
        siemens.ConnectClose( );
    }
 
    #endregion
 
    #region Public Member
 
    /// <summary>
    /// 获取当前的连接对象,方便进行数据交互
    /// </summary>
    /// <returns></returns>
    public HslCommunication.Profinet.Siemens.SiemensS7Net GetSiemens( )
    {
        return siemens;
    }
 
    #endregion
 
 
    #region Private Member
 
    private HslCommunication.Profinet.Siemens.SiemensS7Net siemens;        // 连接对象
 
    #endregion
}

 

定义好之后,就可以创建真正的连接池对象了

 
1
private HslCommunication.Algorithms.ConnectPool.ConnectPool<SiemensConnector> siemensConnect = null;           // 西门子对象的连接池

  

然后初始化变量

 
1
2
3
siemensConnect = new HslCommunication.Algorithms.ConnectPool.ConnectPool<SiemensConnector>( ( ) => { return new SiemensConnector( "192.168.1.195" ); } );
            siemensConnect.MaxConnector = 10;         // 同时存在的最大连接数
            siemensConnect.ConectionExpireTime = 30;  // 连接多久不用就自动回收释放,单位秒

 

 

初始化的时候,有个地方需要注意,连接池需要知道一个信息,如何去创建一个新的连接对象,在这里可能创建默认的SiemesConnector就可以类,但是连接池的管理对象很有可能也是个接口,这时候就需要手动指示如何实例化一个新的对象。这种情况我在使用dapper的ORM的时候,支持mysql和sqlserver两种数据的时候就碰到过。

 

调用连接对象类,以下的代码可以出现在任何的后台线程:

 
1
2
3
4
5
6
7
// 这里的代码在单线程程序情况下,没有什么效果,但是在多线程情况下可以显著提升性能。
// 举例,此处要访问PLC的一个数据
SiemensConnector connector = siemensConnect.GetAvailableConnector( );
short m100 = connector.GetSiemens( ).ReadInt16( "M100" ).Content;
 
// 使用完毕后归还连接
siemensConnect.ReturnConnector( connector );

  

使用完后务必归还连接对象,如果想要获取连接池里已经被激活的连接数

 
1
int online = siemensConnect.UsedConnector;

  

还有,在获取连接对象后,进行操作的时候,务必不要抛出异常,

 


---------------------
作者:dathlin
来源:CNBLOGS
原文:https://www.cnblogs.com/dathlin/p/9191211.html
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

posted @ 2020-07-24 22:59  .Net凯  阅读(286)  评论(0编辑  收藏  举报