如何反复收听串行端口数据核事件以进行超时未收到缓冲区?

发布于 2025-01-22 04:17:11 字数 1217 浏览 0 评论 0原文

我有一个连接到比例尺的权衡指示器(显示)的串行端口连接。

设备B具有3个状态:

  1. 无电(插入)
  2. 电源(插入但不电源)
  3. 在任何状态上都准备就绪(按下电源后)

,我可以连接到串行端口,但我可以仅获取 dataReceived 事件时,当显示就绪状态(#3)时。如果在某些超时, dataReceived 中的无值,我需要触发屏幕以提醒用户设备未就绪状态。当用户在显示屏准备就绪之后和之后按Power时,我可以撤销触发器,以便在 dataReceived 到达时可以继续屏幕。

我尝试使用基于我发现的手动resetevent使用ManualResetevent:

ManualResetEvent DataReceivedEvent = new ManualResetEvent(false);
private void Open_Click(object sender, RoutedEventArgs e)
{
        // All the port initialization
        _serialPort.Open();
        TimeSpan waitTime = TimeSpan.FromMilliseconds(5000);
        bool noData = DataReceivedEvent.WaitOne(waitTime);
}
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
        SerialPort sp = (SerialPort)sender;
        DataReceivedEvent.Set();
}

MRE似乎很有希望,因为我可以等待,设置事件,以便我知道收到数据并在Waitone未设置时返回False,但它冻结了我的UI,并且仅在一次之后运行串行端口开放。

是否可以将ManualResetevent放在线程下,以保持循环并等待而不会冷冻UI?我尝试搜索它,但找不到它。

I have a serial port connection to weighing indicator(display) that connecting to the scale.

Connection diagram

The device B has 3 state:

  1. No Power(Plug off)
  2. Power On(Plug on but not power up)
  3. Display Ready(after press power up)

On any state, I can connect to serial port but I can only get DataReceived event when display ready state (#3). If on certain timeout no value from DataReceived, I need to trigger the screen to alert the user that device is not on ready state. When user press Power On and after the display is ready, then I can revoke the trigger so the screen can continue when DataReceived arrived.

I have try using ManualResetEvent based from what I found:

ManualResetEvent DataReceivedEvent = new ManualResetEvent(false);
private void Open_Click(object sender, RoutedEventArgs e)
{
        // All the port initialization
        _serialPort.Open();
        TimeSpan waitTime = TimeSpan.FromMilliseconds(5000);
        bool noData = DataReceivedEvent.WaitOne(waitTime);
}
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
        SerialPort sp = (SerialPort)sender;
        DataReceivedEvent.Set();
}

The MRE seems promising since I can wait, Set the event so I know the data is received, and return false when WaitOne not Set but it freezing my UI and it just run one time after serial port is open.

Is it possible to put ManualResetEvent under thread to keep loop and wait without freezing UI? I try to search for it but I cannot find it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故人爱我别走 2025-01-29 04:17:11

根据@kunif的建议,我来使用datetime作为基准,以查看设备和显示是否已断开连接。连接状态在设备关闭时相应返回,显示电源并准备就绪。

private DateTime LastBufferTime;
private bool Running { get; set; } = true;
private void Open_Click(object sender, RoutedEventArgs e)
{
    Running = true;
    LastBufferTime = DateTime.Now;
    _serialPort.DataReceived += SerialPortOnDataReceived;
    _serialPort.Open();
    Task.Run(() => ThreadTimer());
}
private async void ThreadTimer()
{
    while (Running)
    {
        if ((DateTime.Now - LastBufferTime).TotalSeconds > 5)
        {
           // No response from DataReceived
        }
        else
        {
           // Response from DataReceived
        }
    }
}
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
    SerialPort sp = (SerialPort)sender;
    LastBufferTime = DateTime.Now;
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
    if (_serialPort != null)
    {
        if (_serialPort.IsOpen)
        {
            _serialPort.Close();
        }
        _serialPort.DataReceived -= SerialPortOnDataReceived;
        _serialPort.Dispose();
        Running = false;
    }
}

Based from @kunif suggestion, I have come to use DateTime as a benchmark to see if the device and display is disconnected. The connection status return accordingly on device turn off, display power up and display ready.

private DateTime LastBufferTime;
private bool Running { get; set; } = true;
private void Open_Click(object sender, RoutedEventArgs e)
{
    Running = true;
    LastBufferTime = DateTime.Now;
    _serialPort.DataReceived += SerialPortOnDataReceived;
    _serialPort.Open();
    Task.Run(() => ThreadTimer());
}
private async void ThreadTimer()
{
    while (Running)
    {
        if ((DateTime.Now - LastBufferTime).TotalSeconds > 5)
        {
           // No response from DataReceived
        }
        else
        {
           // Response from DataReceived
        }
    }
}
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
    SerialPort sp = (SerialPort)sender;
    LastBufferTime = DateTime.Now;
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
    if (_serialPort != null)
    {
        if (_serialPort.IsOpen)
        {
            _serialPort.Close();
        }
        _serialPort.DataReceived -= SerialPortOnDataReceived;
        _serialPort.Dispose();
        Running = false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文