程序被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;
}
构造函数在进程中建立同步连接,类将阻塞,直到连接或失败。
它可能是在事实之后重新开始迭代,因为当它被阻塞时,计时器线程再次触发。try/catch块必须在循环之外处理连接错误,因此它捕获第一个错误并在不完成设备循环的情况下退出。这就是为什么你总是只看到第一个连接。
在我看来,这不是处理连接的好方法。你很容易发生冲突。您应该做的是管理每个连接的状态,并在可以处理任何连接错误的单独线程中尝试每个连接。这样你就可以跟踪它们,而不是试图再次读取当你的计时器触发时,如果一个线程已经在做它。