程序被tcp客户端和定时器c#卡住了

本文关键字:定时器 tcp 客户端 程序 | 更新日期: 2023-09-27 18:17:59

我正在通过Tcp与多个设备通信。

我有一个计时器,每3秒运行一次:

readingTimer = new System.Timers.Timer(3000);
readingTimer.Elapsed += ReadingTimer_Elapsed;
readingTimer.Enabled = true;

然后我迭代经过的事件中的设备列表,并尝试与它们中的每一个建立连接:

private void ReadingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
      foreach (var device in Devices)
      {
          Console.WriteLine($"Reading device {device.number}");
          ReadDevice(device);
      }
}

最后,ReadDevice方法创建一个tcp客户端并尝试读取一些数据:

private string ReadDevice(Device device)
{
     using (TcpClient client = new TcpClient(device.Ip, device.Port))
     {
         //Read Data
         //Return Data
     }
}

问题是我只读取第一个设备,第二个设备上的迭代从未进入。无论我的列表中有多少设备,我总是会得到"阅读设备1"。

附加信息:如果ip不可达,程序被卡在

using (TcpClient client = new TcpClient(device.Ip, device.Port))

,直到它获得超时。在那之后,迭代就被卡住了,终止了;它不会在迭代中移动到下一个设备。我确实有一个尝试/捕获在ReadingTimer_Elapsed与

catch
{
    //Log error message
    continue;
}

程序被tcp客户端和定时器c#卡住了

构造函数在进程中建立同步连接,类将阻塞,直到连接或失败。

它可能是在事实之后重新开始迭代,因为当它被阻塞时,计时器线程再次触发。try/catch块必须在循环之外处理连接错误,因此它捕获第一个错误并在不完成设备循环的情况下退出。这就是为什么你总是只看到第一个连接。

在我看来,这不是处理连接的好方法。你很容易发生冲突。您应该做的是管理每个连接的状态,并在可以处理任何连接错误的单独线程中尝试每个连接。这样你就可以跟踪它们,而不是试图再次读取当你的计时器触发时,如果一个线程已经在做它。