如何在 COM 端口发送和接收之间进行协调

本文关键字:之间 协调 COM | 更新日期: 2023-09-27 18:34:26

我正在尝试重构一些超复杂的遗留代码,这些代码将数据从手持设备发送到手持设备上运行的应用程序,手持设备连接到PC上。

两个应用程序之间有一个遵循协议的"对话";服务器(在PC上运行的应用程序(根据客户端告诉它的内容进行响应,反之亦然。实际上,"对话"在这里可以看到大约三分之二。

无论如何,我的问题是:我怎样才能让客户端等待服务器响应而不中断它,或者认为它不会响应并且无法继续?这就是我现在拥有的:

public class FileXferLegacy : IFileXfer
{
    private SerialPort cereal;
    private String lastDataReceived;
    private String receivedData;
    . . .
    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // This method will be called when there is data waiting in the port's buffer
        try
        {
            receivedData += cereal.ReadLine();
            lastDataReceived = receivedData;
            ExceptionLoggingService.Instance.WriteLog(String.Format("Received {0} in FileXferLegacy.SendDataContentsAsXML", receivedData));
        }
        catch (Exception ex)
        {
            //MessageBox.Show(ex.Message);
        }
    }
    #region IFileFetchSend Members
    . . .
    public void SendDataContentsAsXML(string destinationPath, string data)
    {
        byte[] stuff;
        ExceptionLoggingService.Instance.WriteLog("Reached 
FileXferLegacy.SendDataContentsAsXML");
        cereal.Open();
        stuff = System.Text.UTF8Encoding.UTF8.GetBytes("PING" + "'n");
        cereal.Write(stuff, 0, stuff.Length);
        if (lastDataReceived.Contains("PING")) // Expecting "PING|ACKNOWLEDGE|"
        {
            stuff = 
System.Text.UTF8Encoding.UTF8.GetBytes("LOGIN|foo|000003|LOC_HOST|PPP_PEER|1.4.0.42|bar" + "'n"); 
// TODO: replace this test data with dynamic data
            cereal.Write(stuff, 0, stuff.Length);
        }
        if (lastDataReceived.Contains("JOIN|LEVEL")) // Expecting something like "JOIN|LEVEL|1 
SETTING|ALT_ID|FALSE"
        {
            stuff = System.Text.UTF8Encoding.UTF8.GetBytes("HHTCOMMAND|GETHHTSUPDATE|"); 
            cereal.Write(stuff, 0, stuff.Length);
        }
        . . .
        String lastResponse = lastDataReceived; // Expecting something like 
"RESULT|FILECOMPLETE|INV_000003_whatever(not identical to what was sent earlier!).XML"
        // Parse out and do something with the filename ("INV_000003_whatever(not identical to 
what was sent earlier!).XML" above)
    }

如您所见,客户端/手持设备发送一个字符串;然后读取在DataReceived方法中分配的"lastDataReceived"。但是,如果存在延迟,并且"lastDataReceived"为空怎么办?我需要做什么来强制延迟(不要走极端,导致应用程序在缓慢中看起来像懒惰一样(?或者,如果我完全偏离基础,应该采取什么方式?

如何在 COM 端口发送和接收之间进行协调

一种典型的方法是使用读取器线程,该线程通过阻止读取从端口中提取字节(尽管可以使用异步通知来完成(,并且一旦检测到整个消息已传递,它就会:

  1. 将它们放入阻塞队列(使用者阻止取消排队的调用,直到添加消息或达到超时

  1. 使用包含消息的事件通知侦听器。

这两者中的哪一个在很大程度上取决于这些消息的使用者。 上面的代码将从#1中受益,但如果使用者是UI线程,那么您应该查看#2。

该协议似乎是半双工的,因此通过对 Write/Readline 的同步调用重写它似乎是处理它的最简单方法。