我试图重构一些超复杂的遗留代码,这些代码将数据从手持设备发送到手持设备所连接的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)
}
如您所见,客户端/掌上电脑发送一个字符串;然后读取" lastDataReceived"在DataReceived方法中分配的。但是,如果出现延迟," lastDataReceived"一片空白?我需要做些什么来强制延迟(没有达到会导致应用程序在缓慢中呈现懒惰状态的极端)?或者,如果我完全偏离基础,应该采取什么方式?
答案 0 :(得分:2)
一种典型的方法是使用一个读取器线程,通过阻塞读取从端口拉出字节(尽管可以通过异步通知完成),并且一旦检测到整个消息已经传递,它就会:
或
这两个中的哪一个很大程度上取决于这些消息的消费者。上面的代码将受益于#1,但如果消费者是UI线程,那么你应该看#2。
答案 1 :(得分:2)
该协议似乎是半双工的,因此使用Write / Readline的同步调用重写它似乎是处理它的最简单方法。