【问题标题】:How can I coordinate between COM port sends and receives?如何在 COM 端口发送和接收之间进行协调?
【发布时间】:2014-12-16 00:50:05
【问题描述】:

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

在遵循协议的两个应用程序之间进行“对话”;服务器(PC 上运行的应用程序)根据客户端告诉它的内容做出响应,反之亦然。实际上,在here 的三分之二处可以看到“对话”。

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

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”为空怎么办?我需要做些什么来强制延迟(不要走极端会导致应用程序在其缓慢中显得像树懒一样)?或者如果我完全不在基地应该怎么做?

【问题讨论】:

  • 这是之前的同一个问题还是不同的问题...?
  • 处理延迟往往更多是客户的要求,而不是我们可以客观回答的问题。如果响应延迟,希望它做什么?

标签: c# serial-port compact-framework port windows-ce


【解决方案1】:

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

  1. 将它们放入阻塞队列(消费者会阻塞对出队的调用,直到添加 msg 或达到超时)

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-19
      • 2014-09-20
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多