我编写了一个设置参数的控制台c#程序(我从项目->调试选项中给出了参数)我试图从以太网和串行端口获取数据。
我成功设置了 args 参数,但程序在 string filename = args[4];
控制台突然打开处出现超时错误,并且表现得好像它处于无限循环中,但是没有循环。(在读取 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}");
}
}
}
最佳答案
经过评论里和你的讨论,我想我可以回答你的问题了。
该错误绝对与您怀疑的那行没有任何关系,因为您已经发现了这一点。
您收到一个 TimeoutException
,这是有道理的,因为在 InitilizeSerialPort
中您将读取超时设置为 10ms。这非常短,特别是考虑到您正在阅读整行,而不仅仅是几个字节。
你确实在那里使用了更大的数字。默认值为 500 毫秒,这是一个相当不错的时间。如果您确实需要降低,请尝试一下,但在大多数情况下您不需要更改它。由于您正在阅读一整行,因此实际上 500 毫秒很可能还不够,具体取决于您每行获得的信息量。尝试一些值,直到它起作用(但如果 90 就足够了,请不要将其设置为 100,而是给它一点空间)。
也许值得一提的是,超时当然是最大值。如果指定 1000ms,并且读取需要 100ms,它将在 100ms 后返回,而不等待超时。 要解决此问题,您可以完全删除设置 ReadTimeout 属性的行(它将使用默认值 500 毫秒)或自行将其设置为更高的值。
遗憾的是,我无法帮助您解决您在上一条评论中提到的UnauthorizedAccessException
,因为这很大程度上取决于您的设置。如果您需要帮助,您应该提出一个新问题。
编辑:
顺便说一句,您完全在 GetMessage
中吞下了 TimeoutException
。不要那样做。当另一个错误发生时,您已经在编写控制台消息,因此也可以在那里执行此操作。 SocketException
也是如此,它只是被同一个方法吞掉了。 永远不要吞下异常。
关于c# - System.IO.Ports.dll 错误中的 System.TimeoutException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57675933/