昨天的帖子
http://bbs.csdn.net/topics/391045573
[email protected] 的指点,我改了一下:
if (cs.COMMUNICATION_STATE == COMMUNICATIONSTATE.连接)
{
lock (lockObj)
{
cs.Exception = new Exception("communication timeout");
}
return;
}
cs.Thread = Thread.CurrentThread;
try
{
if (cs.TcpClient == null || !cs.TcpClient.Connected)
{
lock (lockObj)
{
cs.COMMUNICATION_STATE = COMMUNICATIONSTATE.连接;
cs.TriesNum++;
}
cs.TcpClient = new TcpClient(cs.Station.IP, 502);
cs.TcpClient.ReceiveTimeout=500;
cs.TcpClient.SendTimeout=500;
}
TcpClient tc = cs.TcpClient;
lock (lockObj)
{
cs.COMMUNICATION_STATE = COMMUNICATIONSTATE.开始;
}
//读数据,实际就是write之后read
ModbusIpMaster master = ModbusIpMaster.CreateIp(tc);
ushort startAddress = 0;
ushort numInputs = 125;
ushort[] res = master.ReadHoldingRegisters(startAddress, numInputs);
lock (lockObj)
{
//处理数据,保存到数据库
cs.COMMUNICATION_STATE = COMMUNICATIONSTATE.完成;
}
}
catch (Exception e)
{
cs.COMMUNICATION_STATE = COMMUNICATIONSTATE.故障;
}
这样改我希望如果连接不成功能很快的抛出异常,但实际上并没有,仍然是很长时间大概10几秒才会抛出异常。
另外,我希望那个if能保证对一台下位机只连接一次,实际上也不是这样,我用netstat看了一下,每台下位机都有好几个连接established,或者是没有插网线的下位机有很多个syn_sent。
求助,现在应该怎么办?
------解决思路----------------------
if (cs.TcpClient == null
------解决思路----------------------
!cs.TcpClient.Connected)
{
lock (lockObj)
{
cs.COMMUNICATION_STATE = COMMUNICATIONSTATE.连接;
cs.TriesNum++;
}
cs.TcpClient = new TcpClient(cs.Station.IP, 502);
cs.TcpClient.ReceiveTimeout=500;
cs.TcpClient.SendTimeout=500;
}
你这样一段判断下来,肯定会导致你有多个Tcp连接啊,至于为啥超时还是那么长就不知道了,你看下Timeout单位是秒还是毫秒,别搞乌龙了
------解决思路----------------------
try catch范围过大
建议lz先单步跟踪下,看是走到哪一步操作阻塞了。
线程池满了,是因为之前的线程被阻塞了。
找不到阻塞的原因,再多的线程也不够用。
------解决思路----------------------
多线程调试,不能下断点调试,比较靠谱的方法是关键点打印日志
通过日志信息来查找异常点
------解决思路----------------------
TcpClient.ReceiveTimeout=500;
这个是在连接成功,发送数据后等待数据的时间
连接的时间没法控制
如果是网络有问题,网线被拔掉了,那么很快就会抛出异常.
而如果是设备端有问题,你三次握手的数据包要在网络中跑很长时间才会确定找不到设备