Hallo zusammen, ich versuche seit Wochen, eine Datei zeilenweise mit C# (SharpDevelop)an einen Mikrocontroller zu senden und auf die Antwort zu warten. Der Programmablauf ist in etwa folgender: Beim Klick auf Button1 wird folgendes gestartet: Open_File(); Open_SerialPort1(); foreach line in file { create_message(); //Zeile in Datenpaket packen (mit Adresse und Prüfsumme) send_message(); //Nachricht absenden delay(); //warten bis ein Timer abgelaufen ist (ca. 500ms) check_answer(); //Prüfen, ob erwartetes Antwortpaket empfangen wurde } Da das Antwortpaket schon mal ne halbe Sekunde auf sich warten lässt, warte ich immer so lange, bis ich die empfangenen Antwortdaten prüfe. Das kostet unnötig Zeit, weil die Antwort meist schon nach 20 ms da ist. Des Weiteren blockiert die Senderoutine mein Formular, wo ich gerne eine Uhr und einen Progressbalken mit laufen lassen würde. Jetzt habe ich schon verstanden, dass ich das mittels Threading lösen muss. Aber was muss in welchen Thread? Und vor allem wie? Filename und Portparameter sowie Adressdaten stehen in verschiedenen TextBoxen. Diese muss die Senderoutine ja auslesen (oder sollte ich sie ihr übergeben?) Sollte ich jew. einen Thread zum Senden, Empfangen und Dateilesen machen, oder alles in einem Thread machen. Und wie kann ich die Empfangsdaten prüfen, ohne generell so lange zu warten? Ich weiß, das ist ziemlich viel auf einmal, aber vielleicht kann mir ja trotzdem jemand weiterhelfen. Achja – prinzipiell funktioniert das Programm – aber ewig langsam und mit blockiertem System (andere Programme wollen auch nicht mehr so richtig während der Laufzeit und der Lüfter dreht auf Hochtouren) Vielen Dank, Thomas
Hi Thomas, Thomas wrote: > Hallo zusammen, > > ich versuche seit Wochen, eine Datei zeilenweise mit C# (SharpDevelop)an > einen Mikrocontroller zu senden und auf die Antwort zu warten. > Der Programmablauf ist in etwa folgender: Beim Klick auf Button1 wird > folgendes gestartet: > > Open_File(); > Open_SerialPort1(); > foreach line in file > { > create_message(); //Zeile in Datenpaket packen (mit Adresse und > Prüfsumme) > send_message(); //Nachricht absenden > delay(); //warten bis ein Timer abgelaufen ist (ca. 500ms) > check_answer(); //Prüfen, ob erwartetes Antwortpaket empfangen wurde > } > > Da das Antwortpaket schon mal ne halbe Sekunde auf sich warten lässt, > warte ich immer so lange, bis ich die empfangenen Antwortdaten prüfe. > Das kostet unnötig Zeit, weil die Antwort meist schon nach 20 ms da ist. > Des Weiteren blockiert die Senderoutine mein Formular, wo ich gerne eine > Uhr und einen Progressbalken mit laufen lassen würde. Jetzt habe ich > schon verstanden, dass ich das mittels Threading lösen muss. Aber was > muss in welchen Thread? Und vor allem wie? Packe den obigen Code-Abschnitt komplett in einen Thread. Zum Threading gibt's bei MS entsprechende Artikel: http://www.microsoft.com/germany/msdn/library/net/VerwendenVonThreads.mspx?mfr=true http://msdn2.microsoft.com/en-us/library/e1dx6b2h(VS.85).aspx > Filename und Portparameter sowie Adressdaten stehen in verschiedenen > TextBoxen. Diese muss die Senderoutine ja auslesen (oder sollte ich sie > ihr übergeben?) Letzteres. Software sollte strikt aufgeteilt sein in Oberfläche und Datenmodell. Siehe hierzu das MVC Architekturmodell, z.B. in Wikipedia. > Sollte ich jew. einen Thread zum Senden, Empfangen und Dateilesen > machen, oder alles in einem Thread machen. Ein Thread. > Und wie kann ich die > Empfangsdaten prüfen, ohne generell so lange zu warten? ReadTimeout Property beim SerialPort Objekt setzen, z.B. auf 500ms. > Ich weiß, das ist ziemlich viel auf einmal, aber vielleicht kann mir ja > trotzdem jemand weiterhelfen. > Achja – prinzipiell funktioniert das Programm – aber ewig langsam und > mit blockiertem System (andere Programme wollen auch nicht mehr so > richtig während der Laufzeit und der Lüfter dreht auf Hochtouren) Ich weiß nicht wirklich, was Dein delay() Methode veranstaltet. Aber nachdem Du schreibst, daß Dein Rechner auf Vollast läuft, schätze ich mal, daß Du dort einen sogenannten Busy-Wait durchführst (verbraten von CPU-Zeit). Absolut tödlich auf Multiprocessing Systemen. Lasse den delay() Aufruf komplett weg und verwende, wie bereits oben geschrieben den ReadTimeout. > Vielen Dank, Thomas Grüße Markus
Hallo Markus, vielen Dank für Deine Tips. Ich werde vermutlich morgen mal sehen, wie weit ich komme. Bin gerade erstmal dabei das Programm so umzuschreiben, dass ich kaum noch globale Variablen brauche und alles mit Übergabe und Rückgabeparametern erschlage. Mit dem Delay hast Du recht. Ich setze eine Hilfsvariable, starte einen Timer und der setzt sie zurück. Die Zeit schlage ich mit >> while(hifsvariable); << tot. War mir schon klar, dass das nicht OK ist. Werde mal sehen, wie ich das anders löse... Gruß, Thomas
wenn schon warten dann einfach mit Thread.Sleep(500); Und zum Progressbar gibts auch Beispiele in der C# Doku. Wenn die Kommunikation in einen seperaten Thread verlegt wird dann wirst du noch auf das Problem stossen das du aus dem Worker-Thread nicht auf Steuerelement in deinem Dialog zugreifen darfst. Dafür solltest du die Invoke-Beispiele übernehmen.
Hi Thomas, Thomas wrote: > Hallo Markus, > > vielen Dank für Deine Tips. Ich werde vermutlich morgen mal sehen, wie > weit ich komme. Bin gerade erstmal dabei das Programm so umzuschreiben, > dass ich kaum noch globale Variablen brauche und alles mit Übergabe und > Rückgabeparametern erschlage. > Mit dem Delay hast Du recht. Ich setze eine Hilfsvariable, starte einen > Timer und der setzt sie zurück. Die Zeit schlage ich mit >> > while(hifsvariable); << tot. War mir schon klar, dass das nicht OK ist. > Werde mal sehen, wie ich das anders löse... Wie ich bereits oben geschrieben habe, lasse den Aufruf von delay() komplett weg. Du mußt das Lesen vom COM-Port so aufsetzen, daß Du z.B. auf ein Zeichen mit Timeout wartest und wenn das Zeichen ankommt, mit Thread.Sleep(...) nochmals ein paar Millisekunden wartest, damit der Rest der Sendung übertragen werden kann. Die Zeit solltest Du über das Datenvolumen und die Baudrate berechnen können. Dann ermittelst Du mit SerialPort.BytesToRead, wieviel Daten anliegen und liest diese mit SerialPort.Read() ein. Dein delay() ist dabei völlig überflüssig weil das Warten entweder beim Lesen vom Com-Port oder über Thread.Sleep() stattfindet. Beide Arten zu Warten sind multi-processing-verträglich. > > Gruß, Thomas Grüße Markus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.