在while循环中保留变量
本文关键字:保留 变量 循环 while | 更新日期: 2023-09-27 18:04:46
我正在从串行端口(vhf接收器)接收来自不同来源的一些数据,例如汽车。此时整个程序就是一个while循环。当端口打开时,我正在接收数组中的字节并做一些解码。接收和解码while循环1的每个周期的消息。但在一种情况下,有一个信息被分成了奇数部分和偶数部分。我需要解码消息,但在1 while循环中只接收到一部分,例如来自car1的oddpart。下一个while循环可以包含来自car2的oddpart或来自car1的evenpart或来自car3的evenpart等。所以我需要一种方法来存储每辆车的奇偶部分,直到它们都被接收。另一件重要的事情是:从我收到第一部分到收到第二部分应该有10秒的时间窗口。如果超过10秒,第一部分应该被丢弃。我猜数组不会工作,因为我需要一些动态的东西,如列表或字典。
while (serialportopen)
{
//somedecoding I end up with
string hexid;
string oddpart;
string evenpart;
}
我试着创建一个类,像这样的属性来保存消息部分,但我不能创建一个名称为hexid的对象,因为它已经声明。有什么想法包括列表、字典或类吗?
大多数系统处理可变长度数据段的方式是,第一个通过的数据包有一些独特的东西,它通知接收驱动程序它是两部分。例如,它可能只是在第一个数据包上设置或取消MSB(最高有效位),其中0可以表示没有第二个数据包,1可以表示有第二个数据包。然后,当你收到它时,只需屏蔽它,然后调用一个函数来接收第二部分,或者设置一个标志,表示第二部分需要接收,并且它不是一个新数据包。
至于作用域,我有点不清楚你在问什么,但根据上面的代码,如果你在循环外声明变量,即:
string hexid;
string oddpart;
string evenpart;
while (serialportopen)
{
}
它们将为循环的多次迭代维护作用域。无论如何,最好这样做,因为它不会每次都重新声明变量。这可能会被编译器优化掉,也可能不会。
否则,该数据包的位模式有一些独特之处,它通知驱动程序需要另一个数据包。在那个包中可能有一个操作码或命令字段,它可能只是一个屏蔽的问题,调用一个函数来检索和返回第二部分,即
if ((command & CERTAIN_PACKET) == CERTAIN_PACKET)
odpart = GetSecondPart();
我希望这对你有所帮助!
我知道您有办法从一个完整的id中区分奇数部分和偶数部分,并且您有办法告诉您的消息的来源。在这种情况下,我会将奇数部分(如果它们总是首先接收到的)存储在字典中。当我收到一个偶数部分时,我会检查是否有对应的奇数部分存储,如果是这样,我会处理整个东西,否则我会丢弃它。此外,当我收到一个奇怪的部分时,我将启动一个计时器,负责在10秒后将其从字典中删除。由于计时器必须停止,因此它也将存储在字典中。类似这样的内容(这只是一个示例,可能您想要创建一些实例变量以避免到处传递参数):
Dictionary<string, string> oddParts = new Dictionary>string, string>();
Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
while (serialportopen)
{
// somedecoding I end up with
string hexid;
string oddpart;
string evenpart;
// you need something to identify where the message came from and that is present in both the odd and even part (the BF... of your previous question)
string msgId;
if (!String.IsNullOrEmpty(oddpart))
ProcessOddPart(msgId, oddpart, oddParts, timers);
else if (!String.IsNullOrEmpty(evenpart))
hexid = HexIdFromEvenPart(msgId, evenpart, oddparts, timers);
if (!String.IsNullOrEmpty(hexid))
Process(hexid);
}
void Process(string hexid)
{
// your stuff here
}
void ProcessOddPart(string msgId, string oddPart, Dictionary<string, string> oddParts, Dictionary<string, Timer> timers)
{
oddParts[msgId] = oddPart;
System.Timers.Timer tmr = new Timer();
timers[msgId = tmr;
ElapsedEventHandler timePassed = delegate(object anObj, ElapsedEventArgs args) {
tmr.Stop();
oddParts.Remove(msgId);
timers.Remove(msgId);
};
tmr.Interval = 10000;
tmr.Elapsed += timePassed;
tmr.Start();
}
void HexIdFromEvenPart(string msgId, string evenPart, Dictionary<string, string> oddParts, Dictionary<string, Timer> timers)
{
string oddPart;
Timer tmr;
if (timers.TryGetValue(msgId, out tmr))
{
tmr.Stop();
timers.Remove(msgId);
}
if (!oddParts.TryGetValue(msgId, out oddPart))
return null;
return oddPart + evenPart;
}