如何使用串口数据编写自己的Get / Request函数? [英] How to write your own Get / Request function with serial port data?

查看:128
本文介绍了如何使用串口数据编写自己的Get / Request函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与串行端口对话的类,我想模仿Get函数。问题是,串行端口输入的原始数据可能会或可能不会出现。还必须对其进行处理和解析。例如,如果我要获取一个Person对象,则串行端口类将执行此操作。

I have a class that talks to a serial port and I want to mimic a Get function. The problem is, the serial port feeds in raw data which may or may not come. It also has to be processed and parsed. For example, if I want to get a Person object, the serial port class does this.


  1. 一种发送请求的方法

  1. A method to send the request for a Person.

串行设备上发生了某些事情……它可能会响应,但可能不会。

Something happens on the serial device... it might respond, it might not.

字节是通过事件处理程序传入的,该事件处理程序处理并解析所有数据,最后是Person对象。

Bytes come in through an event handler that processes and parses all data, and eventually a Person object.

我想将所有内容包装到一个 GetPerson函数中,但是在连接第1步和第3步时遇到困难。第3步是一个始终运行的函数,更像是一个通用解析器。

I want to wrap that all up into a "GetPerson" function but I'm having difficulty connecting steps in 1 and 3. Step 3 is a function that is always running and is more of a generic parser.

有人可以帮我设计/结构吗?

Can someone help me design/structure this?

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

Also I've tried using a class variable and checking via while statement as shown below but it doesn't check the variable during the while statement for whatever reason:

private Person person;

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


推荐答案

据我所知需要转换 EAP到EAP 。换句话说,以异步等待方式等待某些数据接收事件。您可以使用 TaskComplettionSource<> 。基于本文我试图想象设计合适的解决方案:

As far as I understood you need to convert EAP to TAP. In other words to wait for some data receiving event in async\await manner. You can use TaskComplettionSource<> for that. Based on this article I tried to imagine the design appropriate solution:

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:添加了超时逻辑,另请参见这个问题

UPD: timeout logic is added, see also this question.

希望有帮助。

这篇关于如何使用串口数据编写自己的Get / Request函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆