前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >[C#] 在类里实例化自身的应用实例<上位机通信>

[C#] 在类里实例化自身的应用实例<上位机通信>

作者头像
科控物联
发布2022-03-29 19:50:17
发布2022-03-29 19:50:17
3K00
代码可运行
举报
文章被收录于专栏:科控自动化科控自动化
运行总次数:0
代码可运行

为什么要在类里实例化自身,请参考如下文章:

[C#] 可以在一个类里声明并实例化自身?

比如上位机需要做Modbus的通信.B/S架构,事先不知道有多少个链接.有需要是时候才实例化并保存通信连接...

代码语言:javascript
代码运行次数:0
复制
  public sealed class HoldingRegisters : ModbusTypeAbstract<ushort[]>
  {
        public static HoldingRegisters Instance { get; } = new HoldingRegisters();

    //static HoldingRegisters(){}
    private HoldingRegisters(){}

        public override ushort[] Read(request req)
    {
      return GetOrAddConnection(req.connectiontype, req.destination)?.ReadHoldingRegisters(req.slaveid, req.address, req.count);
    }

    public override void Write(writerequest<ushort[]> wreq)
    {
      GetOrAddConnection(wreq.connectiontype,wreq.destination)?.WriteMultipleRegisters(wreq.slaveid, wreq.address, wreq.data);
    }

  }
代码语言:javascript
代码运行次数:0
复制
  public abstract class ModbusTypeAbstract<T> : IModbusType<T>
  {
    ConcurrentDictionary<string, IModbusMaster> connections = new ConcurrentDictionary<string, IModbusMaster>();

    public abstract T Read(request req);
    public abstract void Write(writerequest<T> wreq);

        public virtual void ConnCount()
        {
            foreach (var conn in connections)
            {
                Console.WriteLine($"{ conn.Key } {conn.Value}");
            }
        }
    /// <summary>
    /// 验证IP连接字符串
    /// </summary>
    /// <param name="conn">IP连接字符串</param>
    /// <param name="ip"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private bool verifyIPConnectionString(string conn, out IPAddress ip, out int port)
    {
      port = 0;
      ip = null;
      var connectionarray = conn.Split(':');
      if (connectionarray.Length != 2)
      {
        return false;
      }

      if (!int.TryParse(connectionarray[1], out port))
      {
        return false;
      }
      if (!IPAddress.TryParse(connectionarray[0], out ip))
      {
        return false;
      }
      return true;
    }
    protected IModbusMaster GetOrAddConnection(ConnectionType ctype, string conn)
    {
            switch (ctype)
       {
        case ConnectionType.SERIALRTU:
          return connections.GetOrAdd(conn, (arg) =>
            {
                            return ModbusSerialMaster.CreateRtu(new SerialPort(conn));
            });
        case ConnectionType.SERIALASCII:
          return connections.GetOrAdd(conn, (arg) =>
            {
                return ModbusSerialMaster.CreateAscii(new SerialPort(conn));
            });
        case ConnectionType.TCP:
          int port; IPAddress ip;
          if (!verifyIPConnectionString(conn, out ip, out port))
          {
            return null;
          }

          return connections.GetOrAdd(conn, (arg) =>
          {
            return ModbusIpMaster.CreateIp(new TcpClient(ip.ToString(), port));
          });
      }
      return null;

    }
  }
}

没有通信请求时,没有实例化通信连接

有个通信请求时候

只要是相同的IP和端口就不会新建连接

不同的IP和端口时:

目的是减少同一个类型new对象的次数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 科控物联 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档