kathi008 Geschrieben 12. Mai 2010 Geschrieben 12. Mai 2010 Hallo Zusammen! Gleich zu meinem Problem: Mein Programm hängt an einem virtuellen COM Port(USB) als Slave und horcht den Bus ab. In regelmässigen Abständen kommt eine Anfrage vom Mastergerät an die Software. Wenn nötig antwortet die Software dem Mastergerät. Funktioniert soweit auch gut. Das blöde ist, die Daten kommen bei der Software ungefähr mit 1 Sekunde verspätung, was bei 19200 Baud zimlich viel ist. Wenn die Software dann Antwortet, kommt es öfters zu Kolisionen am Bus, da Mastergerät schon andere Slaves anfragt. Hat jemand ein Rat wie ich das ganze in Echtzeit gestalten kann? Ich nutze c# .NET2005 die Software hat auch mehrere Fenster, in welchen die Daten dargestellt werden. Die Kommunikation ist mit SerialPort Klasse realisiert und ist Interrupt gesteuert. Zitieren
kathi008 Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Hallo! hab eine Lösung gefunden.:bimei Ich erstelle einfach eine zusätzliche Anwendung, welche nur das Senden und Empfangen am Seriellen Port übernimmt. Die Hauptanwendung und die Hintergrundanwendung lasse ich mittels IPC-Kanal miteinander kommunizieren. Wer aber eine elegantere Lösung parat hat nur her damit! Das Thema kann dann geschlossen werden. Zitieren
Pointerman Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Moin! Wenn ich das richtig sehe, koenntest Du auch einfach einen weiteren Thread verwenden, statt die Funktionalitaet in ein anderes Programm auszulagern. Der einfachste Weg duerfte hier der Backgroundworker sein. Siehe dazu hier:Gewusst wie: Verwenden eines BackgroundWorker Zitieren
kathi008 Geschrieben 27. Mai 2010 Autor Geschrieben 27. Mai 2010 Klar war die Kommunikation in einem Backgroundworker ausgelagert. Das Problem ist: Der Windows reserviert für die gesamte Anwendung bestimmten Speicherbereich und händelt ja die Threads intern nacheinander, abhängig von der Priorität der Threads, ab. Wenn der User ein Mausklick auf eine Form macht, bekommt Diese ganz kurz die höchste Priorität, so dass das Programm sich nicht aufhängt. Dadurch werden alle anderen Thread kurz abgebremst. So habe ich das zumindest verstanden. Wenn ich nun das in eine extra Anwendung auslagere ohne Forms und Grafik, so arbeiten die zwei Anwendungen unabhängig von einander und die Hintergrundanwendung wird durch den User nicht gestört. Zitieren
Pointerman Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Na, klar war das nicht. Hast es ja auch bisher nirgendwo erwaehnt. Ich wuesste jetzt auch nicht, warum ein getrenntes Programm Vorteile gegenueber dem Backgroundworker bringen sollte. Kannst Du vielleicht das Problem noch einmal ausfuehrlich beschreiben. Dass die Probleme durch UI-Interaktionen entstehen hast Du auch erst im letzten Post geschrieben. Zitieren
Guybrush Threepwood Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Wenn ich nun das in eine extra Anwendung auslagere ohne Forms und Grafik, so arbeiten die zwei Anwendungen unabhängig von einander und die Hintergrundanwendung wird durch den User nicht gestört. Naja nicht unbedingt. Wenn die beiden Prozesse nicht gerade auf unterschiedlichen CPUs bzw. Kernen abgearbeitet werden hast du ja das selbe Problem. Du könntestr deinen Prozess zwar als Prirität Echtzeit geben aber wie sich das genau auswirkt kann ich nicht sagen... Zitieren
Bubble Geschrieben 27. Mai 2010 Geschrieben 27. Mai 2010 Das blöde ist, die Daten kommen bei der Software ungefähr mit 1 Sekunde verspätung, Hat jemand ein Rat wie ich das ganze in Echtzeit gestalten kann? Zuerst musst Du festlegen, was "Echtzeit" für Dich in diesem Fall konkret bedeuten soll. Sprich, welche Verzögerung im Durchschnitt akzeptabel ist und ob Du akzeptieren kannst, wenn es auch (gelegentlich) viel länger dauern könnte, auch wenn dies in der Praxis nicht unbedingt oder nur selten auftritt, oder ob festgelegte Reaktionszeiten zugesichert werden müssen. Zitieren
kathi008 Geschrieben 28. Mai 2010 Autor Geschrieben 28. Mai 2010 Hallo! Meine Anwendung dient zur Parametrierung eines Gerätes, welches als Master am Seriellen Bus angeschlossen ist. Das heißt: dieses Gerät schickt regelmäßig eine Anfrage an alle angeschlossenen Geräte, auch an den PC. Die Reaktionszeit auf die Anfrage beträgt 20 -60 ms. Schafft der PC in dieser Zeit nicht zu antworten, soll er auf die nächste Anfrage warten und dann die Anwort wegschicken. Die Daten werden per SeriellPort- Klasse eingelesen. Die Klasse puffert die Daten, sodass, wenn der PC die Anfrage abholt, eigentlich schon andere Geräte angefragt werden. Wenn nun der PC antwortet, kommt es zur Kollision. Die Kommunikation lief anfangs in einem Backgroundworker, bei dem ich auch die Priorität 'Echtzeit' eingestellt habe. Leider brachte es keine Verbesserungen. Erst als ich extra eine Anwendung dafür erstellt habe, ging es. Wenn die beiden Prozesse nicht gerade auf unterschiedlichen CPUs bzw. Kernen abgearbeitet werden hast du ja das selbe Problem. Guybrush Threepwood Du hast natürlich Recht, das muss ich noch ausprobieren. Aber hier hat der Windows die Chance die verschiedenen Prozesse auf verschiedene Kernel zu verteilen, was bei einer einzigen Anwendung schwierig wäre. Zitieren
Pointerman Geschrieben 29. Mai 2010 Geschrieben 29. Mai 2010 Du hast natürlich Recht, das muss ich noch ausprobieren. Aber hier hat der Windows die Chance die verschiedenen Prozesse auf verschiedene Kernel zu verteilen, was bei einer einzigen Anwendung schwierig wäre. Nein, dashat nichts damit zu tun, ob es eine Anwendung ist, oder nicht. Sobald Du Threads verwendest, sollten diese auch parallel verarbeitet werden können. Hast Du vielleicht eine Synchronisierung verwendet, die zu Verklemmungen führt und Du diese einfach durch das Auslagern in eine andere Anwendung umgangen hast? Zitieren
kathi008 Geschrieben 1. Juni 2010 Autor Geschrieben 1. Juni 2010 Hallo zusammen! Ich habe nun meine Anwendung noch mal gründlich durchgesehen und neu aufgebaut. Das Auslagern der Kommunikation in eine extra Anwendung hat mir geholfen diese von dem Hauptprgramm richtig zu trennen. Ich habe nun die Kommunikation in einen Backgroundworker(BGW1) verpackt, welcher wiederrum aus einem anderen Backgroundworker(BGW2) aufgerufen wird. BGW1 erledigt reine Kommunikation. BGW2 entscheidet, wie mit den Daten weiterverfahren wird und löst ein paar Events aus, auf die im Hauptfenster reagiert wird. Soweit so gut. Es funktioniert nun auch in Echtzeit. Danke für die Infos. Ein neues Problem: BGW1 wird durch Usereingaben gestartet. Innerhalb der Do_Work() läuft eine 'endlose' while- Schleife, die auch nur durch Usereingaben abgebrochen wird. In der while- Schleife steht kein Code, weil die Kommunikation über SeriellPort- Klasse und deren Events läuft. Ich muss halt den BGW1 irgendwie blockieren, damit er weiterläuft. Das eigentliche Problem: die while- Schleife nimmt bei meinem DualCore Processor 50% von den CPU- Ressourcen. Die Anwendung sollte aber mehrmals auf einem Rechner gestartet werden können. Damit wird aber der PC lamgelegt! Gibt es ein Ersatz für die While - Schleife? Hab in MSDN AutoResetEvent gefunden... Kann man mit Hilfe von AutoResetEvent den Thread solange blockieren, bis der User den Befehl zum Schließen gibt? Wird dabei die SeriellPort Klasse mit deren Events auch blockiert? Zitieren
Gateway_man Geschrieben 1. Juni 2010 Geschrieben 1. Juni 2010 An deiner Stelle würd ich die Backroundworker einstampfen und direkt mit der Threak Klasse Arbeiten. Da machste statt 2 Backroundworker 2 Threads. Vorteil: -Du kannst prioritäten der einzelnen Thread festlegen. -Du kannst jeden Thread nach belieben Pausieren (Suspend nennt sich die Funktion). Lg Gateway Zitieren
Klotzkopp Geschrieben 1. Juni 2010 Geschrieben 1. Juni 2010 Suspend nennt sich die FunktionUnd man sollte sie nur benutzen, wenn man ganz genau weiß, was man tut. Diese Funktion ist nicht zur Synchronisierung geeignet, oder dazu, einen Thread zu "parken". Man kann damit sehr leicht das ganze Programm zum Hängen bringen. Sie Remarks-Abschnitt in der MSDN-Library-Seite von Thread.Suspend. Ganz grob gesagt, sollte man von Thread.Suspend die Finger lassen, wenn man nicht gerade einen Debugger schreibt. Zitieren
Pointerman Geschrieben 1. Juni 2010 Geschrieben 1. Juni 2010 Moin! Schau Dir mal Thread.Sleep an. Sleep klingt ersteinmal böse, ist ja aber kein aktives warten. Infinite oder 0 als Parameter könnten Dich interessieren. Siee auch: Thread.Sleep-Methode (Int32) (System.Threading) Zitieren
kathi008 Geschrieben 11. Juni 2010 Autor Geschrieben 11. Juni 2010 Hallo Zusammen! Hab mit dem AutoResetEvent gelöst. Funktioniert soweit. Wirklich in Echtzeit die Daten einzulesen habe ich dann doch nicht geschaft, fehlen nur ein paar Millisekunden. Dadurch wächst der Berg an Daten im Empfangspuffer der SerialPort Klassen. Hab mit dem DiscardInPuffer gelöst. Dadurch geht zwar einiges verloren, aber bei der Funktion ist es nicht schlimm. Ein anderes Problem: Meine Anwendung beinhalt eine DataLogger Funktion. Hier werden die Daten in einem RichTextBox dargestellt, welcher nach bestimmter zeit geleert wird und die Daten in einer Datei gespeichert werden. Das Problem: Es wird nur die Anzeige von dem RichTextBox geleert, der allocierter Speicher bleibt aber beibehalten und wird erst mit Beender der Anwendung freigegeben. Wenn die Anwendung Tage läuft, reicht irgendwann der Speicher nicht mehr aus. Das zerstören des Steuerelemets hat nix gebracht, da der Speicher anscheinend der gesamten Anwendung zugesichert wird. Hab mit dem Memory Profiler beobachtet: Solange der Text dem RichTextBox hinzugefügt wird, steigen Gen0 - Gen3 permanent. Schließe ich die Form mit dem RichTextBox, bleibt es auf der letzten Höhe und fällt nicht zurück. Beim erneuten Starten steigt das Ganze ab dem letzten Punkt weiter! Wie kann ich zusammen mit dem leeren (evtl. Zerstören) des RichTextBoxes auch den Speicher freigeben? Danke im Voraus. Zitieren
Guybrush Threepwood Geschrieben 11. Juni 2010 Geschrieben 11. Juni 2010 Wenn die Anwendung Tage läuft, reicht irgendwann der Speicher nicht mehr aus. Ist das wirklich so passiert oder vermutestr du das das so ist? Denn nicht verwendeter Speicher wird normalerweise dann freigegeben wenn er benötigt wird. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.