如何使用串口数据编写自己的获取/请求函数?



我有一个与串行端口通信的类,我想模仿一个 Get 函数。问题是,串行端口输入的原始数据可能会也可能不会。它还必须被处理和解析。例如,如果我想获取一个 Person 对象,串行端口类会这样做。

  1. 为人员发送请求的方法。

  2. 串行设备上发生了一些事情...它可能会回应,也可能不会。

  3. 字节通过处理和分析所有数据的事件处理程序传入,并最终通过 Person 对象传入。

我想将所有这些内容包装成"GetPerson"函数,但我很难连接 1 和 3 中的步骤。步骤 3 是一个始终运行的函数,更像是一个通用解析器。

有人可以帮我设计/构建这个吗?

编辑:我也尝试使用类变量并通过while语句进行检查,如下所示,但由于任何原因,它在while语句期间不会检查变量:

private Person person;
public Person GetPerson()
{
...
while (person == null) {}
return person;
}

据我了解,您需要将EAP转换为TAP。换句话说,以异步\await方式等待某些数据接收事件。您可以使用TaskComplettionSource<>。基于这篇文章,我试图想象设计合适的解决方案:

public class PersonSerialPort : IDisposable
{
private readonly SerialPort port;
/// <summary>
/// Timeout in milliseconds
/// </summary>
private const int Timeout = 5000;
public PersonSerialPort()
{
// port initializing here
port = new SerialPort(/*your parameters here*/);
port.Open();
}
public async Task<Person> GetPerson()
{
// set up the task completion source
var tcs = new TaskCompletionSource<Person>();
// handler of DataReceived event of port
var handler = default(SerialDataReceivedEventHandler);
handler = (sender, eventArgs) =>
{
try
{
Person result = new Person();
// some logic for filling Person fields
// or set it null or whatever you need
// you are free to not set result and wait for next event fired too
tcs.SetResult(result);
}
finally
{
port.DataReceived -= handler;
}
};
port.DataReceived += handler;
// send request for person
port.Write("Give a person number 1");
if (await Task.WhenAny(tcs.Task, Task.Delay(Timeout)) == tcs.Task)
{
return tcs.Task.Result;
}
else
{
port.DataReceived -= handler;
throw new TimeoutException("Timeout has expired");
}
}
public void Dispose()
{
port?.Dispose();
}
}

UPD:添加了超时逻辑,另请参阅此问题。

希望对您有所帮助。

最新更新