保持变量不受while循环的影响

时间:2011-08-08 21:24:04

标签: c# arrays class naming

我从串口接收(甚高频接收器)来自不同来源的一些数据可以说比如汽车。目前整个程序是一个循环。当端口打开时,我在数组中接收字节并进行一些解码。接收并解码while循环1消息的每个循环。但在一种情况下,有一条消息被分成奇数部分和偶数部分。我需要两个解码消息,但只有一个部分在1中被接收,而循环让我们从 car1 说出oddpart。下一个while循环可能包含来自 car2 的oddpart或者来自 car1 的偶数部分或者来自 car3 等的部分。所以我需要一种方法来存储奇数偶数每辆车的部件,直到收到它们。另一件重要的事情是:从收到第一部分到收到第二部分的那一刻起,应该有10秒的时间窗口。如果通过10秒,则应该标记第一部分。我猜数组不会工作,因为我需要动态像List或字典。

while (serialportopen)
{
//somedecoding I end up with
string hexid;
string oddpart;
string evenpart;
}

我尝试创建一个类like this ,其中包含保存消息部分的属性,但是我无法创建一个名为hexid的对象,因为它已经被声明了。任何想法,包括列表词典或类?

2 个答案:

答案 0 :(得分:1)

大多数系统在处理可变长度数据段时的方式是,第一个数据包通过时会有一些独特之处,通知接收驱动程序它是两部分。例如,它可能只是在第一个数据包上设置或取消设置的MSB(最高有效位),其中0可以表示没有第二个数据包,1可以表示存在第二个数据包。然后,只需要在获得它时屏蔽它,调用函数接收第二部分,或设置第二部分需要接收的标志,并且它不是新数据包。

至于范围,我对你要问的内容有点模糊,但基于上面的代码,如果你在循环之外声明变量,即:。

string hexid;
string oddpart;
string evenpart;
while (serialportopen)
{

}

他们将保持循环的多次迭代的范围。不管怎样,最好这样做,因为它不会每次都重新声明变量。这可能会也可能不会被编译器优化。

否则,有一些关于该数据包的位模式的信息,通知驱动程序需要另一个数据包。该数据包中可能存在操作码或命令字段,它可能只是一个屏蔽问题,调用函数来检索并返回第二部分,即。

if ((command & CERTAIN_PACKET) == CERTAIN_PACKET)
    odpart = GetSecondPart();

我希望能帮到你一些!

答案 1 :(得分:0)

我知道你有一种方法可以从一个偶数部分,一个完整的id中找出一个奇怪的部分,并且你有办法告诉你信息的来源。在这种情况下,我会在字典中存储oddparts(如果它们总是先收到的那些)。当我收到一个偶数部分时,我会检查是否存有相应的奇数部分,如果是这种情况我会处理整个事情,否则我会丢弃它。此外,当我收到奇怪的部分时,我会启动一个计时器,负责在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;
}