System.TimeoutException 中的 System.IO.Ports.dll 错误
System.TimeoutException in System.IO.Ports.dll error
我编写了一个设置参数的控制台 c# 程序(我从项目->调试选项中提供了参数)我正在尝试从以太网和串行端口获取数据。
我成功设置了 args 参数,但程序在 string filename = args[4];
超时错误 控制台突然打开 并且表现得好像它是在无限循环中bu没有循环。(读取while之前发生错误)
对于那些想阅读那些参数是什么的人; 1 = IP,[2] = 端口号,[3] = 端口名(COM3),[4] = 文件名。
[编辑]
考虑到我可能同时从以太网和串行端口的两个连接获取数据,超时是为了防止数据丢失。
我还想说添加 DataReceived += new SerialDataReceivedEventHandler(ProcessReceivedData);
而不是 while 没有任何好处,因为它再次发生在 while 循环之前。
有人知道吗?
static int Main(string[] args)
{
int err = 0;
if (args.Length == 5)
{
IPAddress IP = IPAddress.Parse(args[1]);
int CmdPort;
if (int.TryParse(args[2],out CmdPort))
{
string filename = args[4];//takes filename
String root = @".\"; //DEFAULT EXE PATH ROOT
string path_combined;
path_combined = Path.Combine(root, filename);
StreamWriter sw;
try
{
sw = File.AppendText(path_combined);
p = new SPWrapper(IP, CmdPort, args[3], sw);
if (p.Init())
{
while (!Console.KeyAvailable)
{
p.GetMessage();
Thread.Sleep(100);
}
p.Close();
}
sw.Flush();
sw.Close();
}
catch (System.IndexOutOfRangeException ex)
{
System.ArgumentException argEx = new System.ArgumentException("File creation failed!", ex);
err = -2;
throw argEx;
}
}
else
{
err = -1;
}
}
if (err!=0)
{
Console.WriteLine("Not Enough Arguments");
Console.WriteLine("Logger IP Port ComPort FileName");
}
return err;
}//end of main
Here is my other class
public class SPWrapper
{
private System.IO.Ports.SerialPort CmdSerialPort;
public DateTime lastComm = DateTime.MinValue;
public UdpClient udpClient_Cmd;
public volatile bool _enabled_Cmd;
public static int Ethernet_Packet_Header_Length = 14;
private IPAddress IP { get; set; }
private int Cmd_Port { get; set; }
private string SerialPortName;
private StreamWriter swLog;
private bool _closing = false;
private IPEndPoint IPE_Cmd;
private void CloseEthernet()
{
udpClient_Cmd?.Close();
}
private void CloseSerialPort()
{
if (CmdSerialPort.IsOpen)
{
CmdSerialPort.Close();
}
}
public void Close()
{
_closing = true;
CloseEthernet();
CloseSerialPort();
swLog = null;
}
private bool InitilizeSerialPort(string portName)
{
try
{
CmdSerialPort.PortName = portName;
CmdSerialPort.BaudRate = 115200;
CmdSerialPort.ReadTimeout = 10; // 10milisecond read timeout
CmdSerialPort.Open();
if (CmdSerialPort.IsOpen)
{
return true;
}
return false;
}
catch (UnauthorizedAccessException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
catch (ArgumentOutOfRangeException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
catch (ArgumentException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
}
private bool InitializeEthernet()
{
bool retVal = true;
IPE_Cmd = new IPEndPoint(IP, Cmd_Port);
try
{
udpClient_Cmd = new UdpClient();
udpClient_Cmd.Client.Bind(IPE_Cmd);
udpClient_Cmd.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10);
}
catch (Exception ex)
{
retVal = false;
udpClient_Cmd?.Close();
udpClient_Cmd = null;
Debug.WriteLine(ex.ToString());
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.InnerException?.ToString());
}
return retVal;
}
public SPWrapper(IPAddress ip, int cmdPort, string comPort, StreamWriter sw)
{
IP = ip;
Cmd_Port = cmdPort;
SerialPortName = comPort;
swLog = sw;
CmdSerialPort = new SerialPort();
}
public bool Init()
{
return (InitializeEthernet() && InitilizeSerialPort(SerialPortName));
}
internal void GetMessage()
{
lastComm = DateTime.Now;
string SerialMessage = "";
try
{
SerialMessage = CmdSerialPort.ReadLine();
}
catch (TimeoutException)
{
}
if (SerialMessage.Length >0)
{
SerialMessage = SerialMessage.Trim(' ').Trim('\n').Trim('\r');
swLog.WriteLine($"{CmdSerialPort.PortName}\t{lastComm}\t{SerialMessage}");
}
IPEndPoint e = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBytes = null;
try
{
receiveBytes = udpClient_Cmd?.Receive(ref e);
}
catch (ObjectDisposedException)
{
udpClient_Cmd?.Close();
udpClient_Cmd = null;
}
catch(SocketException)
{
}
if (receiveBytes != null)
{
string UDP_Read_Message = System.Text.Encoding.UTF8.GetString(receiveBytes.Skip(Ethernet_Packet_Header_Length).ToArray());
swLog.WriteLine($"{e}\t{lastComm}\t{UDP_Read_Message}");
}
}
}
您是否检查过以确保 args[1]
、args[2]
等是您认为的那样?尝试将 args[1]
更改为 args[0]
并将其余部分减少一个 args[2]
-> args[1]
等 Reference and Reference 2.
经过在评论中与您的讨论,我想我可以回答您的问题。
这个错误肯定与您怀疑的那一行没有任何关系,因为您自己已经发现了。
您收到一个 TimeoutException
,这是有道理的,因为在 InitilizeSerialPort
中您将读取超时设置为 10 毫秒。这非常短,特别是考虑到您正在阅读整行,而不仅仅是几个字节。
你真的在那里使用了更大的数字。默认值为 500 毫秒,这是一个很好的时间。如果你真的需要降低,试试看,但在大多数情况下你不需要改变它。由于您正在阅读整行,因此 500 毫秒实际上很可能不够,具体取决于您每行获得的信息量。尝试一些值直到它起作用(但如果 90 就足够了,请不要将其设置为 100,给它一点空间)。
也许值得一提,超时当然是最大的。如果您指定 1000 毫秒并且读取需要 100 毫秒,它将在 100 毫秒后 return 而不是等待超时。
要解决此问题,您可以完全删除设置 ReadTimeout
-属性 的行(它将使用默认值 500 毫秒),或者您自己将其设置为更高的值。
遗憾的是,对于您在上一条评论中提到的 UnauthorizedAccessException
,我无法为您提供帮助,因为这在很大程度上取决于您的设置。如果您需要帮助,您应该提出一个新问题。
编辑:
顺便说一句,您在 GetMessage
中完全吞下了 TimeoutException
。不要那样做。当另一个错误发生时,你已经在写一个控制台消息,所以也在那里做。 SocketException
也是如此,它只是用相同的方法被吞噬了。 永远不要吞下异常。
我编写了一个设置参数的控制台 c# 程序(我从项目->调试选项中提供了参数)我正在尝试从以太网和串行端口获取数据。
我成功设置了 args 参数,但程序在 string filename = args[4];
超时错误 控制台突然打开 并且表现得好像它是在无限循环中bu没有循环。(读取while之前发生错误)
对于那些想阅读那些参数是什么的人; 1 = IP,[2] = 端口号,[3] = 端口名(COM3),[4] = 文件名。
[编辑] 考虑到我可能同时从以太网和串行端口的两个连接获取数据,超时是为了防止数据丢失。
我还想说添加 DataReceived += new SerialDataReceivedEventHandler(ProcessReceivedData);
而不是 while 没有任何好处,因为它再次发生在 while 循环之前。
有人知道吗?
static int Main(string[] args)
{
int err = 0;
if (args.Length == 5)
{
IPAddress IP = IPAddress.Parse(args[1]);
int CmdPort;
if (int.TryParse(args[2],out CmdPort))
{
string filename = args[4];//takes filename
String root = @".\"; //DEFAULT EXE PATH ROOT
string path_combined;
path_combined = Path.Combine(root, filename);
StreamWriter sw;
try
{
sw = File.AppendText(path_combined);
p = new SPWrapper(IP, CmdPort, args[3], sw);
if (p.Init())
{
while (!Console.KeyAvailable)
{
p.GetMessage();
Thread.Sleep(100);
}
p.Close();
}
sw.Flush();
sw.Close();
}
catch (System.IndexOutOfRangeException ex)
{
System.ArgumentException argEx = new System.ArgumentException("File creation failed!", ex);
err = -2;
throw argEx;
}
}
else
{
err = -1;
}
}
if (err!=0)
{
Console.WriteLine("Not Enough Arguments");
Console.WriteLine("Logger IP Port ComPort FileName");
}
return err;
}//end of main
Here is my other class
public class SPWrapper
{
private System.IO.Ports.SerialPort CmdSerialPort;
public DateTime lastComm = DateTime.MinValue;
public UdpClient udpClient_Cmd;
public volatile bool _enabled_Cmd;
public static int Ethernet_Packet_Header_Length = 14;
private IPAddress IP { get; set; }
private int Cmd_Port { get; set; }
private string SerialPortName;
private StreamWriter swLog;
private bool _closing = false;
private IPEndPoint IPE_Cmd;
private void CloseEthernet()
{
udpClient_Cmd?.Close();
}
private void CloseSerialPort()
{
if (CmdSerialPort.IsOpen)
{
CmdSerialPort.Close();
}
}
public void Close()
{
_closing = true;
CloseEthernet();
CloseSerialPort();
swLog = null;
}
private bool InitilizeSerialPort(string portName)
{
try
{
CmdSerialPort.PortName = portName;
CmdSerialPort.BaudRate = 115200;
CmdSerialPort.ReadTimeout = 10; // 10milisecond read timeout
CmdSerialPort.Open();
if (CmdSerialPort.IsOpen)
{
return true;
}
return false;
}
catch (UnauthorizedAccessException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
catch (ArgumentOutOfRangeException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
catch (ArgumentException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
return false;
}
}
private bool InitializeEthernet()
{
bool retVal = true;
IPE_Cmd = new IPEndPoint(IP, Cmd_Port);
try
{
udpClient_Cmd = new UdpClient();
udpClient_Cmd.Client.Bind(IPE_Cmd);
udpClient_Cmd.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10);
}
catch (Exception ex)
{
retVal = false;
udpClient_Cmd?.Close();
udpClient_Cmd = null;
Debug.WriteLine(ex.ToString());
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.InnerException?.ToString());
}
return retVal;
}
public SPWrapper(IPAddress ip, int cmdPort, string comPort, StreamWriter sw)
{
IP = ip;
Cmd_Port = cmdPort;
SerialPortName = comPort;
swLog = sw;
CmdSerialPort = new SerialPort();
}
public bool Init()
{
return (InitializeEthernet() && InitilizeSerialPort(SerialPortName));
}
internal void GetMessage()
{
lastComm = DateTime.Now;
string SerialMessage = "";
try
{
SerialMessage = CmdSerialPort.ReadLine();
}
catch (TimeoutException)
{
}
if (SerialMessage.Length >0)
{
SerialMessage = SerialMessage.Trim(' ').Trim('\n').Trim('\r');
swLog.WriteLine($"{CmdSerialPort.PortName}\t{lastComm}\t{SerialMessage}");
}
IPEndPoint e = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBytes = null;
try
{
receiveBytes = udpClient_Cmd?.Receive(ref e);
}
catch (ObjectDisposedException)
{
udpClient_Cmd?.Close();
udpClient_Cmd = null;
}
catch(SocketException)
{
}
if (receiveBytes != null)
{
string UDP_Read_Message = System.Text.Encoding.UTF8.GetString(receiveBytes.Skip(Ethernet_Packet_Header_Length).ToArray());
swLog.WriteLine($"{e}\t{lastComm}\t{UDP_Read_Message}");
}
}
}
您是否检查过以确保 args[1]
、args[2]
等是您认为的那样?尝试将 args[1]
更改为 args[0]
并将其余部分减少一个 args[2]
-> args[1]
等 Reference and Reference 2.
经过在评论中与您的讨论,我想我可以回答您的问题。
这个错误肯定与您怀疑的那一行没有任何关系,因为您自己已经发现了。
您收到一个 TimeoutException
,这是有道理的,因为在 InitilizeSerialPort
中您将读取超时设置为 10 毫秒。这非常短,特别是考虑到您正在阅读整行,而不仅仅是几个字节。
你真的在那里使用了更大的数字。默认值为 500 毫秒,这是一个很好的时间。如果你真的需要降低,试试看,但在大多数情况下你不需要改变它。由于您正在阅读整行,因此 500 毫秒实际上很可能不够,具体取决于您每行获得的信息量。尝试一些值直到它起作用(但如果 90 就足够了,请不要将其设置为 100,给它一点空间)。
也许值得一提,超时当然是最大的。如果您指定 1000 毫秒并且读取需要 100 毫秒,它将在 100 毫秒后 return 而不是等待超时。
要解决此问题,您可以完全删除设置 ReadTimeout
-属性 的行(它将使用默认值 500 毫秒),或者您自己将其设置为更高的值。
遗憾的是,对于您在上一条评论中提到的 UnauthorizedAccessException
,我无法为您提供帮助,因为这在很大程度上取决于您的设置。如果您需要帮助,您应该提出一个新问题。
编辑:
顺便说一句,您在 GetMessage
中完全吞下了 TimeoutException
。不要那样做。当另一个错误发生时,你已经在写一个控制台消息,所以也在那里做。 SocketException
也是如此,它只是用相同的方法被吞噬了。 永远不要吞下异常。