Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Merkwürdiges Verhalten bei DataReceived
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

Merkwürdiges Verhalten bei DataReceived

beantworten | zitieren | melden

Hallo zusammen

Ich habe ein unerklärliches Verhalten in folgendem Aufruf.

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                string str = serialPort1.ReadExisting();
                //MessageBox.Show(str);
                BeginInvoke(new auswertung_delegate(auswertung), str);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            serialPort1.DiscardInBuffer();
        }

Wenn ich die hier auskommentierte Messagebox in den Ablauf hinein nehme, wird auf jedes Ereignis reagiert, also ich bekomme eine Ausgabe bei jedem mal wenn ich etwas schicke. Es reagiert wie erwartet. Alles ist gut, nehme ich nun die Messagebox heraus, so reagiert die Anwendung auf das erste Senden, und danach "beliebig". Beliebig heißt das mal nach jedem den 10. Senden, mal auf 2 aufeinander folgenden Sendungen.

Kann das mit Threading zu tun haben, oder ist es nur ein "Bug"?
Hat jemand eine Idee?

Danke schonmal
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Daniel83,

leider sind unerklärlichen Verhalten unerklärlich. Wenn es sich also hier wirklich um ein unerklärlichen Verhalten handeln würde, dann dürftest du nicht auf eine Antwort hoffen. :-)

Klar ist, dass MessageBoxen den Ablauf der Anwendung - teilweise gravierend und unerwartet - ändern.
Zitat
Beliebig heißt das mal nach jedem den 10. Senden, mal auf 2 aufeinander folgenden Sendungen.
Kannst du das bitte genauer erklären. Meinst du damit, dass du DataReceived nur einmal für zwei Datenpakete bekommst? Oder was anderes?

herbivore
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

Habe die Anwendung auf einem Controlpanel, welchem ich zu Testzwecken über ein Programm auf dem PC via Comport telegramme zuschicke.
D.h. wenn ich von meinem PC das erste Telegramm schicke wird in jedem Fall richtig reagiert.
Habe ich die MessageBox im Code drin, wird auf jedes Protokol das ich sende erst mit der MessageBox und danach entsprechend der darauf folgenden Rutine reagiert.
Nehme ich die MessageBox heraus, so wird immer noch auf das erste Telegramm reagiert, (auch richtig) jedoch nicht unbedingt auf das darauf folgenden.
Also drücke ich in meinem Programm zum Senden wiederholt auf den Senden Button. Das Programm auf dem ControlPanel, also das welches diese Telegramme auswerten soll, reagiert dann nur noch manchmal. Dabei ist es egal, ob ich einige Sekunden Pause mache oder sehr schnell klicke.
Mal reagiert das Programm auf zwei aufeinander folgende Protokolle, mal macht es 10 oder 20 mal Senden gar nichts.

Ablauf:
Senden Reaktion
Protokoll Ja
Protokoll Nein
Protokoll Nein
Protokoll Nein
Protokoll Ja
Protokoll Ja
Protokoll Nein
...

Ich hoffe das ich so das Phänomen erschöpfend beschrieben habe.
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

DiscardInBuffer() würd ich rausnehmen.
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

Danke sehr, das wars Tatsächlich. Löscht ReadExisting den Speicher selber? Also hab ich das dann doppelt gemacht?
Probiere gerade was passiert wenn sehr viele Daten kommen. Aber bis jetzt scheint es keinen überlauf oder so etwas zu geben.
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

Habe mal mit sehr viele Daten geschickt. Mein Code ist Offensichtlich nicht sehr perfomant, Habe aber dadurch feststellen können, Das der Code, je länger er arbeitet immer langsamer wird. Am Anfang wurden etwa 5-7 Auswertungen pro Sekunde durchgeführt, zum Schluss waren es nur noch 2 Auswertungen je Sekunde. Das spricht doch dafür, das sich ein "großer Berg" Daten angesammelt hat, den ich ja nun nicht mehr lösche(glaub ich). Die Hilfe konnte mir zu der Frage ob ich den Einlesespeicher lösche (mit readexisting) nicht weiter Helfen.
Ander zwischen Frage, ich gebe in eine Textbox mit Multiline und Scrollbar aus, ist da die Max Zeilenanzahl vorgegeben? Denn ich kann nur bis zu einer gewissen Stelle herunter scrollen, danach andert sich der inhalt nicht mehr, Obwohl er ja zumindest eine Andere Zeit anzeigen muss. Es sind bis dahin aber bestimmt einige hundert Zeilen.
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

Habe mal nachgeguckt. Ein string, zumindest war das bei C++ beim Ansi string so, hat 4GB kapazität, ich kan darstellen, also das was ich scrollen kann sind 951 Zeilen mit jeweils 63 Zeichen. Das sind aber wenn ein zeichen ein Byte hat nur ca 60kb, das ist ein bischen wenig finde ich, evtl. Zeilen Beschränkung?
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Zitat von Daniel83
Löscht ReadExisting den Speicher selber? Also hab ich das dann doppelt gemacht?

Um Speicher und "Überläufe" mache dir mal keine Gedanken. Das Problem dürfte sein, dass du z.B. mit ReadExisting() z.B. 8 Bytes liest. Dann kommen z.B. nochmal 2 neue Bytes rein und bevor du die wieder abholst, hast du sie schon mit DiscardInBuffer() rausgeworfen. Du verlierst also Zeichen.

DiscardInBuffer() verwendet man eigentlich eher im Kontext des synchronen Modells (also ohne DataReceivedEvent) um sauber "aufzusetzen".
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Das Problem mit der Geschwindigkeit wird in deinem UI liegen. Zeig uns mal den Code der Funktion auswertung().
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1.688

beantworten | zitieren | melden

Hallo Daniel83,

vielleicht schaust Du einfach mal in die TextBox-Dokumentation?

Außerdem ist es eine ganz schlechte Idee, zwei verschiedene Probleme in einem Thread zu behandeln.
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

private void auswertung(string str)//str ist das eingelesene des COM Ports
        {
            string ausgabe="";

            Buffer += str;
            befehl tmp=new befehl();
            ausgabe = tmp.Befehl(Buffer);
            if (ausgabe != "" && ausgabe != "ungültig")
            {
                zähler++;
                tb_ausgabe.Text = tb_ausgabe.Text.Insert(17, "\r\n" + DateTime.Now 
                            + " : " + ausgabe + " von:" + tmp.ausgabe_Adr(Buffer) 
                            + zähler.ToString());
            }
            try
            {
                int start = tmp.get_Start(Buffer);
                int ende = tmp.get_Ende(Buffer);
                if (start ≥ 0 && ende > 0)
                {
                    if (ende - start + 1 ≤ Buffer.Length)
                    {
                        Buffer = Buffer.Remove(start, ende - start + 1);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString()+"Fehler in auswertung");
            }
            
        }

public string Befehl(string eingang)//eingang alles im eigenen Eingabe Puffer
            {
                if (eingang.Length ≥ 5)
                {
                    get_Positions(eingang);
                    if (OK)
                    {
                        if (pos_befehl > 0)
                        {
                            return ausgabe_Befehl(eingang);
                        }
                    }
                    return "ungültig";
                }
                else
                {
                    return"";
                }
            }

private void get_Positions(string eingang)
            {
                pos_start = get_Start(eingang);
                if (pos_start ≥ 0)
                {
                    pos_ende = get_Ende(eingang);
                    if (pos_start ≥ 0 && pos_ende > 0)
                    {
                        pos_befehl = get_Befehl(eingang);
                        pos_adr = get_Adr(eingang);
                    }
                }
                if (pos_start ≥ 0 && pos_ende > 0 && pos_befehl > 0)
                {
                    OK = true;
                }
            }

public int get_Start(string eingang)
            {
                int pos = 0;
                try
                {
                    pos = eingang.IndexOf("\u0002");
                }
                catch (Exception e)
                {
                    //MessageBox.Show("index 0002 failed " + e.Message);
                    pos = -1;
                }

                return pos;
            }

private int get_Befehl(string info)
            {
                int pos = -1;
                try
                {
                    int min = 3;
                    int max = 6;
                    if (max ≥ info.Length)
                    {
                        for (; min < info.Length; min++)
                        {
                            for (int i = 0; i < moegl_Befehl.Length; i++)
                            {
                                if (info[min] == moegl_Befehl[i])
                                {
                                    return pos = min;
                                }
                            }
                        }
                    }
                    else
                    {
                        for (; min < max; min++)
                        {
                            for (int i = 0; i < moegl_Befehl.Length; i++)
                            {
                                if (info[min] == moegl_Befehl[i])
                                {
                                    return pos = min;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    //MessageBox.Show("  pos of Befehl Excep" + e);
                    pos = -1;
                }
                return pos;
            }

get_ende und get Adresse sind sehr ähnlich, deshalb Poste ich die der5 übersicht halber nicht
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Hast du mal probiert, den Text neu in die Textbox zu schreiben anstelle anzufügen? Wirds dann schneller?
private Nachricht | Beiträge des Benutzers
Daniel83
myCSharp.de - Member



Dabei seit:
Beiträge: 171
Herkunft: Bielefeld Deutschland

Themenstarter:

beantworten | zitieren | melden

Habe gerade 11.000 durchläufe gemacht, läuft mit ersetzen ohne Probleme und sehr schnell, ist jedoch nicht sinnvoll. gibt es eine effektive variante, also ohne ebiges schrittweise durchgehen, den TextBox Inhalt auf 500 Zeilen oder so zu begrenzen, Sowas könnte ich machen.
Aber ersetzen würde den ganzen Sinn zunichte machen, ich will ja zustände mitschreiben, die auch mal sehr schnell reinkommen können, wäre doof wenn man dann irgendwas wichtiges nicht sehen könnte.
private Nachricht | Beiträge des Benutzers