2011-08-08 54 views
-3

我從一個串口(vhf接收器)接收一些來自不同來源的數據,比如汽車。目前的整個計劃都是一段時間的循環。當端口打開時,我正在接收數組中的字節並做一些解碼。 while循環1消息的每個週期都被接收和解碼。但是在一個案例中,有一個信息被分成奇數部分和偶數部分。我需要兩個解碼消息,但只有一個部分收到1,而週期可以說,從car1 oddpart。而週期可能包含oddpart從CAR2或evenpart從CAR 1或evenpart從的Car3等第二天所以我需要一種方法來每輛車的奇偶部分存儲,直到他們都被接收。還有一件重要的事情:從我收到第一部分到我收到第二部分的那一刻,應該有10秒的時間窗口。如果通過10秒,則應該甩開第一部分。我猜數組不會工作,因爲我需要像列表或字典一樣的動態。將變量保留在while循環之外

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

我試圖創建一個類like this與屬性保存消息的部分,但因爲它已經宣佈我不能創建一個名爲hexid的對象。任何想法包括列出詞典或類?

+0

請不要在「C#」前加標題。這就是我們在SO上的標籤。 –

+1

請說出爲什麼這不是您早期問題的重複,請訪問http://stackoverflow.com/questions/6976156/giving-a-class-instance-the-name-of-a-variable。 –

+0

,因爲它的另一個問題 –

回答

0

我知道你有一種方法可以從一個偶數部分,從一個完整的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; 
} 
1

大多數系統在處理可變長度的數據段時都會這樣做,對於通過接收驅動程序通知它是兩部分的第一個數據包有一些獨特之處。例如,它可能僅僅是第一個數據包上的MSB(最高有效位)設置或取消設置,其中0表示不存在第二個數據包,而1可能表示存在第二個數據包。然後,只需要在獲取它時屏蔽它,然後調用一個函數來接收第二部分,或設置一個需要接收第二部分的標誌,並且這不是一個新數據包。

至於範圍,我是那種你在問什麼的雲裏霧裏,但基於上面的代碼,如果你聲明外循環的變量,即:

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

} 

他們」將保持循環的多次迭代的範圍。無論如何,最好不要這樣做,因爲它不會每次重新聲明變量。這可能會或可能不會被編譯器優化。

否則,有關該數據包的位模式的通知驅動程序需要另一個數據包的東西。在這個數據包中可能有一個操作碼或命令字段,它可能只是一個掩碼問題,調用一個函數來檢索並返回第二部分,即。

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

我希望能幫到你一些!