Problem - IndexOutOfRangeException

0

Witam, spotkałem się z zaskakującą sytuacją, która polega na:
zrobiłem soft, który odbiera dan z rs232 i na ich podstawie coś tam robi.

 
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string data = "";
            while (serialPort1.BytesToRead > 0) {
                data += System.Convert.ToString((byte)serialPort1.ReadByte(), 16) + " "; 
            }
            
            if (data.Length >21)
            {
                this.BeginInvoke(new SetTextDeleg(ReadCM), new object[] { data.Substring(0, data.Length - 1) });
            }
                if(monitor == 1) this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data.Substring(0, data.Length - 1) });
            

        }

program wysyła do ReadCM paczkę danych a ReadCM sprawdza co to i coś tam z tym robi.

 
        private void ReadCM(string sx_all)
        {
            string[] sx = sx_all.Split(' ');
            int[] bajt = new int[sx.Length];
            string[] bajts = new string[sx.Length];
            try
            {
                string adres = "", kanal = "";
                string info = "", typ = "";
                
                for (int i = 0; i < sx.Length; i++)
                {
                    if (sx[i] != "" && sx[i] != null)
                    {
                        bajt[i] = Convert.ToInt32(sx[i], 16); // konwersja z string hex na int dec
                        bajts[i] = sx[i];
                    }
                }

                ...

                adres = obn + "." + rgn + "." + mdn;
                kanal = kan;

                int odp = 0;
                string pom = "";
                string kodkarty = "";
                
                //CM
                switch (bajt[6])
                {

                    case 0xBC:		//temp odp. manual

                        typ = "TEMP";

                        //stanTemp(temp + " " + tempzad + " " + offset + " " + tempDO + " " + tempOD + " " + adres);
                        string temp = bajt[7].ToString();
                        if (int.Parse(bajt[8].ToString()) > 0) { temp += ",5"; }
                        string temp_zadana = bajt[9].ToString();
                        if (int.Parse(bajt[10].ToString()) > 0) { temp_zadana += ",5"; }
                        string temp_od = bajt[11].ToString();
                        if (int.Parse(bajt[12].ToString()) > 0) { temp_od += ",5"; }
                        string temp_do = bajt[13].ToString();
                        if (int.Parse(bajt[14].ToString()) > 0) { temp_do += ",5"; }

                        stanTemp(temp + " " + temp_zadana + " " + temp_do + " " + temp_od + " " + adres);
                        //Thread t2 = new Thread(() => instrukcjeWarunkowe("Obwód", adres, obwodybin));
                        //t2.Start();

                        break;
 
                }
                
            }
            catch (IndexOutOfRangeException ex)
            {
                MessageBox.Show("An index was out of range!" + ex.Message);
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Some sort of error occured: " + ex.Message);
            }
            finally
            {
                //MessageBox.Show("It's the end of our try block. Time to clean up!");
            }

        }

Problem polega na tym, że wszystko pięknie działa gdy skompiluję i uruchomię program bezpośrednio w visualstudio (visualstudio przesyła program po USB na urządzenie i na nim go uruchamia), ale gdy przeniosę pliki na urządzenie (Win CE) i odpalę je bezpośrednio na nim to podczas wykonywania ReadCM program "wywala" błąd IndexOutOfRangeException.
Nie wiem co jest grana. Czarna magia? :(
Bardzo proszę o pomoc.

0

pewnie sx_all ma mniej spacji, niż oczekujesz, przez co tablica bajt jest krótsza od 15. razem z ex.Message rzuć ex.StackTrace i sx_all, to będziesz wiedział co, w której linii i dlaczego.

0

Chyba muszę zacząć promować używanie Trace czy innych mechanizmów logowania i monitorowania.
Nawiązując do tego co napisał ŁF. Jeśli MessageBox ma być informacją dla użytkownika, to inne informacje o błędzie powinieneś zapisać do Trace. Można łatwo konfigurować czy, kiedy i jak przechwytywać informacje z Trace. Więc podczas testów ustawiasz że łapiesz wszystko i monitorujesz działanie aplikacji, w wersji produkcyjnej łapiesz krytyczne błędy.
To tak w skrócie.

0

jeśli mowa o narzędziach do logowania stanu programu, to polecam log4net. mało inwazyjny, bardzo prosty w użyciu i nietrudny do skonfigurowania, a jednocześnie ma duże możliwości.

0

Tak, tak też kiedyś używałem log4netów, nhibernatów i innych wynalazków, ale jako że nie pasjonuję się pisaniem wszystkich konfigów z palca, ani poprawianiem tego co popsuły niedopracowane generatory konfigów, wolę jednak Microsoft Enterprise Library i Entity Framework. To jest rzeczywiście łatwe do skonfigurowania, dobra konfiguracja log4neta zajmuje dłużej.

Ale, co kto lubi.

0

Wg mnie zarówno konfiguracja tradycyjnego Trace, log4net, EntLib jest tak samo łatwa z palca. Oczywiście jak napisał othello EntLib ma tę przewagą że ma fajny dodatek gui do tego.
Ważne żeby nauczyć się używać chociaż jednego komponentu do logowania i używać!

1 użytkowników online, w tym zalogowanych: 0, gości: 1