我正在尝试在微处理器和c#表单应用程序之间进行串行通信。
问题是,来自微处理器的数据可以在2秒或5秒或10秒内完成。我的意思是没有特定的时间,我想听端口并获取数据,如果它是2秒,如果不是,等待数据,直到它来。
我尝试使用serialport.readline();但是当readline阻塞时,表单会挂起,所以当我这样做时,我试图与backgroundworkers一起工作,当backgroundworker忙时,我无法关闭表单,因为readline命令会阻止整个程序。
我所说的是,请告诉我一些关于收听端口的线索,而未来的数据时间并不具体。
感谢您的时间(抱歉英语不太好)
答案 0 :(得分:1)
您可以使用SerialPort.DataReceived Event获取数据异步。在创建SerialPort
类的实例后,您可以向SerialPort
添加事件处理程序。如果收到数据,则调用事件处理程序。
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
在处理程序内部,您可以从输入缓冲区中读取数据并使用它执行任何操作。
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
//Do what ever you want with the data
}
这是一种非常常见的解决方案,可以在不正常的时间步骤中获取数据,从而在不阻止应用程序的情况下运行应用程序。
答案 1 :(得分:1)
您可以使用DataReceived事件。每当新数据到达您的端口时,它都会被触发。你需要像这样注册:
SerialPort port = new SerialPort(/*your specification*/);
port.DataReceived += Port_DataReceived;
在事件处理程序中,您将读出传入的数据
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = sender as SerialPort;
if (port != null)
{
var incoming_message = port.ReadExisting();
}
}
现在您只需打开端口即可自动收听。注意!传入的数据将到达与主线程不同的线程。因此,如果您想使用表单的控件进行显示,则需要使用BeginInvoke
如果您的数据标记在最后\n
,则可以尝试使用ReadLine
方法:
var incoming_message = port.ReadLine();
或者您可以尝试ReadTo
var incoming_message = port.ReadTo("\n");
修改强>
如果这么长时间,你应该分批阅读。您也可以尝试在while循环中处理它。
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = sender as SerialPort;
string message = "";
if (port != null)
{
while(port.BytesToRead > 0)
{
message += port.ReadExisting();
System.Threading.Thread.Sleep(500); // give the device time to send data
}
}
}
编辑2:
如果要存储数据,请在事件处理程序之外声明List<string>
,并在完全读取时添加字符串。
List<string> dataStorage = new List<string>();
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = sender as SerialPort;
string message = "";
if (port != null)
{
while(port.BytesToRead > 0)
{
message += port.ReadExisting();
System.Threading.Thread.Sleep(500); // give the device time to send data
}
// add now the entire read string to the list
dataStorage(message);
}
}
由于事件处理程序不知道您是否已发送A
或B
,只需在一个列表中收集整个收到的消息。您知道发送命令的顺序,因此稍后您可以取出相应的消息并使用Split
获取数组中的400个条目:
string [] A_array_data = dataStorage[0].Split(" ");