C# - Com 端口无法在 Windows 服务上工作

问题描述 投票:0回答:1

我对 COM 端口没有太多经验,我正在尝试创建一个具有以下目标的 Windows 服务:

打开列表中的所有 COM 端口名称,例如(“COM1、COM2、COM3、...”)。

打开可用的 COM 端口,并显示无法打开的错误。 打开的 COM 端口应该能够读取数据,因为数据将随机发送到它们。 根据发送数据的COM口,会经过一个开关来决定它的流程。

问题是,当我运行该服务并使用任何打开的 COM 端口时,它仅适用于该端口,之后就无法与任何其他端口一起使用。 也就是说,在假设的场景中,如果只打开COM3和COM4,两者都应该接收数据,但如果我先使用COM3,COM4不会响应,只剩下COM3。我该如何解决这个问题?

这是我的代码。

  • 开始服务-

      sapEntities db = new sapEntities();
    
      public Service1()
      {
          InitializeComponent();
      }
    
      protected override void OnStart(string[] args)
      {
          try
          {
              WriteToFile($"Call COM port is started at {DateTime.Now}");
              COMDataLog($"Ready at {DateTime.Now}");
              StringCollection stringCollection = Properties.Settings.Default.List_COM;
              string[] ports = new string[stringCollection.Count];
              stringCollection.CopyTo(ports, 0);
    
              foreach (string portName in ports)
              {
                  try
                  {
                      SerialPort sp = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
                      sp.Handshake = Handshake.RequestToSend;
                      sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                      sp.Open();
                      WriteToFile($"{portName} is open at {DateTime.Now}");
                  }
                  catch (UnauthorizedAccessException uae)
                  {
                      WriteToFile($"{portName} Error UnauthorizedAccessException: {uae.Message} at {DateTime.Now}");
                  }
                  catch (ArgumentException ae)
                  {
                      WriteToFile($"{portName} Error ArgumentException: {ae.Message} at {DateTime.Now}");
                  }
                  catch (IOException ioe)
                  {
                      WriteToFile($"{portName} Error IOException: {ioe.Message} at {DateTime.Now}");
                  }
                  catch (Exception ex)
                  {
                      WriteToFile($"{portName} Error: {ex.Message} at {DateTime.Now}");
                  }
              }
          }
          catch (Exception ex)
          {
              WriteToFile($"Error: {ex.Message} at {DateTime.Now}");
          }
      }
    
  • 接收数据-

      private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
      {
          try
          {
              SerialPort sp = (SerialPort)sender;
    
              if (sp != null)
              {
                  Thread.Sleep(100);
                  string data = sp.ReadExisting();
                  string cPort = sp.PortName;
                  ProcessData(db, cPort, data);
              }
              else
              {
                  WriteToFile($"DataReceivedHandler error: SerialPort object is null at {DateTime.Now}");
              }
          }
          catch (Exception ex)
          {
              WriteToFile($"DataReceivedHandler error: {ex.Message} at {DateTime.Now} ");
          }
      }
    
  • 根据发送信息的COM端口进行数据处理(COM端口选项还有很多,我只放了几个,以免代码太混乱)。

      private void ProcessData(sapEntities db, string port, string data)
      {
          var ins_light = new real_light();
    
          switch (port)
          {
              case "COM1":
                  WriteToFile($"COM1 Read: {data} at {DateTime.Now}");
                  COMDataLog($"COM1 Read: {data}");
    
                  ins_light = new real_light
                  {
                      lgt_date = DateTime.Now,
                      lgt_data = data,
                      lgt_ref = 1
                  };
    
                  db.real_light.Add(ins_light);
    
                  try
                  {
                      db.SaveChanges();
    
                      foreach (var entry in b.ChangeTracker.Entries())
                      {
                          entry.State = EntityState.Detached;
                      }
    
                      WriteToFile($"COM1 Data stored correctly: {data} at {DateTime.Now}");
    
                  }
                  catch (Exception ex)
                  {
                      foreach (var entry in db.ChangeTracker.Entries())
                      {
                          entry.State = EntityState.Detached;
                      }
                      WriteToFile($"COM1 Error data stored {ex.Message} at {DateTime.Now}");
                  }
                  break;
              case "COM2":
                  WriteToFile($"COM2 Read: {data} at {DateTime.Now}");
                  COMDataLog($"COM2 Read: {data}");
                  ins_light = new real_light
                  {
                      lgt_date = DateTime.Now,
                      lgt_data = data,
                      lgt_ref = 2
                  };
                  db.real_light.Add(ins_light);
    
                  try
                  {
                      db.SaveChanges();
                      foreach (var entry in db.ChangeTracker.Entries())
                      {
                          entry.State = EntityState.Detached;
                      }
                      WriteToFile($"COM1 Data stored correctly: {data} at {DateTime.Now}");
    
                  }
                  catch (Exception ex)
                  {
                      foreach (var entry in db.ChangeTracker.Entries())
                      {
                          entry.State = EntityState.Detached;
                      }
                      WriteToFile($"COM1 Error data stored {ex.Message} at {DateTime.Now}");
                  }
                  break;
              default:
                  WriteToFile($"Unknown port: {port}");
                  break;
          }
      }
    
c# serial-port windows-services
1个回答
0
投票

搜索有关串口的信息,我忘记添加 2 个重要的东西,现在可以了。

1.- 收藏系列列表

private List<SerialPort> serialPorts = new List<SerialPort>();

2.- 为每个 com 端口分配一个 DataReceived

sp.DataReceived += (sender, e) => DataReceivedHandler(sender, e, portName); 

因此,完成了编辑。

        private List<SerialPort> serialPorts = new List<SerialPort>();
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                WriteToFile($"Call COM port is started at {DateTime.Now}");
                COMDataLog($"Ready at {DateTime.Now}");
                StringCollection stringCollection = Properties.Settings.Default.List_COM;
                string[] ports = new string[stringCollection.Count];
                stringCollection.CopyTo(ports, 0);

                foreach (string portName in ports)
                {
                    try
                    {
                        SerialPort sp = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
                        sp.Handshake = Handshake.RequestToSend;
                        sp.DataReceived += (sender, e) => DataReceivedHandler(sender, e, portName); 
                        sp.Open();
                        serialPorts.Add(sp);
                        WriteToFile($"{portName} is open at {DateTime.Now}");
                    }
                    catch (UnauthorizedAccessException uae)
                    {
                        WriteToFile($"{portName} Error UnauthorizedAccessException: {uae.Message} at {DateTime.Now}");
                    }
                    catch (ArgumentException ae)
                    {
                        WriteToFile($"{portName} Error ArgumentException: {ae.Message} at {DateTime.Now}");
                    }
                    catch (IOException ioe)
                    {
                        WriteToFile($"{portName} Error IOException: {ioe.Message} at {DateTime.Now}");
                    }
                    catch (Exception ex)
                    {
                        WriteToFile($"{portName} Error: {ex.Message} at {DateTime.Now}");
                    }
                }
            }
            catch (Exception ex)
            {
                WriteToFile($"Error: {ex.Message} at {DateTime.Now}");
            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.