Zum Inhalt springen

(CF) Windows.Forms-GUI + Timer entkoppeln


Empfohlene Beiträge

Geschrieben

Folgendes Problem: Ich habe eine (Compact Framework 2.0) Anwendung geschrieben, welche eine Windows.Forms-Benutzeroberfläche besitzt. Diese Benutzeroberfläche soll, sobald sich die anzuzeigenden Daten ändern, aktualisiert werden.

Derzeit ist die Aktualisierung der GUI über einen (System.Windows.Forms) Timer realisiert, welcher in etwa alle 2 Sekunden ausgelöst wird und welcher wiederum die Daten berechnen lässt. Die Daten werden über einen Web-Service auf einem Server berechnet, daher dauert das Beschaffen/Berechnen der Daten jedesmal ebenfalls so ca. 2 Sekunden. Das Problem hierbei ist, dass die GUI sehr langsam reagiert, d.h. wenn eine Schaltfläche gedrückt wird, kann es mehrere Sekunden dauern, bis das Programm ein Feedback gibt.

Daher würde ich das Beschaffen der Daten gerne über einen zusätzlichen, eigenen Thread von der GUI entkoppeln, bloß wie mache ich sowas?

Geschrieben

Hallo,

ich habe etwas Probleme mit diesem 2 Sekunden System klar zu kommen, denn selbst wenn Du das in einen eigenen Thread packst, fragst Du alle 2 Sekunden beim Server nach "sind Daten da".

Warum setzt hier nicht auf ein bidirektionales System, das beim ersten Connect einen Eventlistener auf dem Server registriert und über den dann Deine Anwendung benachrichtigt wird, wenn sich Daten verändert haben bzw. direkt die neuen Daten geliefert bekommt?

HTH Phil

Geschrieben

Ja ich weiß, die Sache mit dem Timer ist ziemlich unglücklich, allerdings ist ein timer unumgänglich. Die Sache ist folgende: der Client (Pocket PC) muss alle x Sekunden seine Gerätedaten auslesen und an den Server schicken. Aus diesen Daten berechnet der Server Nutzdaten, die zurück an den Pocket PC geschickt werden sollen. Um also Nutzdaten berechnen zu können, werden alle x Sekunden Gerätedaten übertragen.

Die Idee, dass der Server sich meldet, sobald er mit der Berechnung fertig ist, ist an sich nicht schlecht, allerdings dauert die Berechnung ja nicht soo lange, vermutlich dauert das zusätzliche Connecten für die Serverantwort mehr zeit, als man einsparen würde. Außerdem möchte ich, dass die gesamte Kommunikation asynchron abläuft, damit während des Webservice-Aufrufes die GUI nicht blockiert wird.

Ich hatte mir sowas gedacht, wie dass die Kommunikation mit dem Server in einem eigenen thread passiert, nur weiß ich nicht ganz, wie ich die Nutzdaten dann an den GUI-Thread weiterreichen kann!?

Geschrieben

Hallo,

Ja ich weiß, die Sache mit dem Timer ist ziemlich unglücklich, allerdings ist ein timer unumgänglich. Die Sache ist folgende: der Client (Pocket PC) muss alle x Sekunden seine Gerätedaten auslesen und an den Server schicken. Aus diesen Daten berechnet der Server Nutzdaten, die zurück an den Pocket PC geschickt werden sollen. Um also Nutzdaten berechnen zu können, werden alle x Sekunden Gerätedaten übertragen.

Warum? Die Gerätedaten des Pocket PC's ändern sich doch nicht alle Sekunden, die sind statisch?

Die Idee, dass der Server sich meldet, sobald er mit der Berechnung fertig ist, ist an sich nicht schlecht, allerdings dauert die Berechnung ja nicht soo lange, vermutlich dauert das zusätzliche Connecten für die Serverantwort mehr zeit, als man einsparen würde. Außerdem möchte ich, dass die gesamte Kommunikation asynchron abläuft, damit während des Webservice-Aufrufes die GUI nicht blockiert wird.

Zu einem, warum musst Du während der Bearbeitung durch den Webservice die Verbindung trennen? Wenn Es kaum Zeit in Anspruch nimmt, dann connecte den Webservice, gib ihm über die Parameter die Daten mit und der Webservice kann Dir ja einen Returnwert liefern, der z.B. ein Array sein kann.

Ich hatte mir sowas gedacht, wie dass die Kommunikation mit dem Server in einem eigenen thread passiert, nur weiß ich nicht ganz, wie ich die Nutzdaten dann an den GUI-Thread weiterreichen kann!?

Gib, wenn Du Deinen Thread erzeugst, ihm einfach das GUI Objekt / Eventobjekt o.ä. einfach mit. Hier würde sich sicher die Systematik eines Eventlisteners anbieten, über den Du dann die Daten tauschst

Aber vielleicht schielderst Du mal die ganzen Zusammenhänge, ich habe irgendwie das Gefühl - nimm es mir bitte nicht übel - aber das ganze etwas auf die schnell zusammen gebaut ist.

HTH Phil

Geschrieben

Hi,

Warum? Die Gerätedaten des Pocket PC's ändern sich doch nicht alle Sekunden, die sind statisch?

Keine voreiligen Schlüsse! ;) Nein, die Daten, die ich übertrage, sind aktuelle Feldstärken, welche direkt vom WLAN-Adapter gelesen werden. Somit ziemlich veränderlich.

Zu einem, warum musst Du während der Bearbeitung durch den Webservice die Verbindung trennen? Wenn Es kaum Zeit in Anspruch nimmt, dann connecte den Webservice, gib ihm über die Parameter die Daten mit und der Webservice kann Dir ja einen Returnwert liefern, der z.B. ein Array sein kann.

Ja, genau so mache ich es doch im Moment auch, d.h. eine Funktion mit Parametern über Webservice aufrufen und auf den Return-Wert warten. Nur soll das Warten auf den Return-Wert nicht im aktuellen GUI-Thread, sondern einem eigenen passieren.

Gib, wenn Du Deinen Thread erzeugst, ihm einfach das GUI Objekt / Eventobjekt o.ä. einfach mit. Hier würde sich sicher die Systematik eines Eventlisteners anbieten, über den Du dann die Daten tauschst

Aber vielleicht schielderst Du mal die ganzen Zusammenhänge, ich habe irgendwie das Gefühl - nimm es mir bitte nicht übel - aber das ganze etwas auf die schnell zusammen gebaut ist.

Ok danke für den Vorschlag. Werd erstmal ausprobieren, dem Thread das GUI-Objekt zu übergeben; allerdings widerspricht dies irgendwie dem Grundsatz, dass man Fachkonzept (Programmlogik) und GUI-Schichten voneinander trennen soll und erstere eigentlich nicht auf zweitere zugreifen soll. Naja egal, hauptsache es klappt erstmal, dann kann man weiter schauen.

Thx

Oli

Geschrieben

Hallo,

das mit dem WLAN finde ich doch eine recht interessante Sache.

Werd erstmal ausprobieren, dem Thread das GUI-Objekt zu übergeben; allerdings widerspricht dies irgendwie dem Grundsatz, dass man Fachkonzept (Programmlogik) und GUI-Schichten voneinander trennen soll und erstere eigentlich nicht auf zweitere zugreifen soll. Naja egal, hauptsache es klappt erstmal, dann kann man weiter schauen.

Ich hatte ein ähnliches Problem mal unter Java zu realisieren. Der Server hat beim Starten ein Eventhandlerobjekt erzeugt, an dem sich dann jeder Client beim connect angemeldet hat. Verschiedene Clients wurden nun vom Server gruppiert und wenn ein Client aus dieser Gruppe die Anwendung gestartet hatte, mussten alle Clients darüber benachrichtigt werden und mussten in einer bestimmten Reihenfolge die Daten dann verarbeiten.

Ich hatte auf den Clients immer eine GUI, im Hintergrund lief der Connect Thread. Im Client selbst war ebenfalls ein EvenListener/Handler implementiert, einmal um GUI Events abzufangen und einmal die Events vom Server zu verarbeiten bzw. neue zu generieren. Aus der GUI-Sicht vom Client gab es eine zentrale Schnittstelle, der Server hat letztendlich die Events an alle Clients verteilt, so dass daraus eine (lokale) Applikation (aus Clientsicht) entstanden ist.

HTH Phil

  • 2 Monate später...
Geschrieben

Nochmal nach einiger zeit meine Lösung hierzu.

Habe inzwischen das Problem anderweitig gelöst. Softwaretechnisch vielleicht nicht am elegantesten, aber naja.

Habe das ganze jetzt über einen Timer der Klasse System.Threading.Timer gelöst. Dieser führt die Methode, die den Webservice aufruft, asynchron aus. In dieser Methode schreibe ich das Ergebnis in eine statische Variable x, welche auch von GUI-Seite aus zugreifbar ist.

Für die GUI verwende ich wiederum einen Timer der Klasse System.Windows.Forms.Timer, welcher regelmäßig die Variable x abfragt und bei Veränderung ggfls. reagiert.

Jetzt reagiert die GUI merklich schneller auf Eingaben.

Bei der Taktung des Timers muss darauf geachtet werden, dass die Taktung nicht schneller ist, als die Methoden-Aufrufe abgearbeitet werden können, ansonsten ist bald kein freier Thread mehr aus dem internen Threadpool verfügbar.

Naja ich sag ja, nicht unbedingt elegant aber funktioniert erstmal.

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...