我有一个与串口通信的类,我想模仿Get函数。问题是,串口输入原始数据,可能会也可能不会。它还必须进行处理和解析。例如,如果我想获取Person对象,则串行端口类执行此操作。
我想把它全部包装成一个“GetPerson”函数,但是我在连接1和3中的步骤时遇到了困难。步骤3是一个始终运行的函数,它更像是一个通用的解析器。
有人可以帮我设计/构建这个吗?
编辑:我也尝试使用类变量并通过while语句检查如下所示,但它不会在while语句中检查变量,无论出于何种原因:
private Person person;
public Person GetPerson()
{
...
while (person == null) {}
return person;
}
据我所知,你需要转换EAP to TAP。换句话说,以async \ await方式等待一些数据接收事件。你可以使用TaskComplettionSource<>
。基于this article,我试图想象设计合适的解决方案:
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:添加了超时逻辑,另请参阅this question。
希望能帮助到你。