Thread-Programmierung [Erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Thread-Programmierung [Erledigt]

Beitrag von UliTs »

Hallo allerseits,

ich möchte in einem Programmteil selbigen beenden, wenn der Benutzer eine Zeitlang keine Eingaben getätigt hat.
Deshalb habe ich einen Thread zur "Überwachung" eingeführt. Sobald die Zeit abgelaufen ist, soll dieser Thread mittels "Keyboard" ein ESC-Zeichen in den Tastaturpuffer des Programmteils schreiben. Geht das überhaupt und wenn ja, wie?

Uli
Zuletzt geändert von UliTs am Mo, 25. Jun 2012 12:53, insgesamt 1-mal geändert.
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread-Programmierung

Beitrag von brandelh »

In welchem Wartezustand bist du denn ?

@ GET kann man besser mit clear gets verlassen ...
Bei einer Schleife würde ich eine Flag-Variable für die Abbruchbedingung vorziehen, diese könnte per Funktion(static) oder als Parameter des Threadaufrufs verfügbar sein.

PostAppEvent() kann man ja das Ziel übergeben, wenn das ein Control oder ein Dialog ist (auch als Parameter ?) sollte das gehen.
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Thread-Programmierung

Beitrag von georg »

Guten Morgen, Uli -


ich gehe davon aus, dass Du zwei Threads verwendest. Du startest den Überwachungsthread #2 aus dem normalen Programmteil # und übergibst eine Referenz auf das Thread-Objekt #1.

Stellst Du dann fest, dass die Zeit abgelaufen ist, sendest Du ein Event an das Thread-Objekt #1:

Code: Alles auswählen

PostAppEvent(my_Event, , , oThread1)
Den Event-Loop im Thread-Objekt #1 musst Du so anpassen, dass dieses Event abgefangen wird, um dann darauf zu reagieren:

Code: Alles auswählen

nEvent := AppEvent(...)
DO CASE
  CASE nEvent == my_Event
    //Programmteil beenden, z.B. durch KeyBoard(K_KESC)
  OTHERWISE
    oXbp:handleEvent(...)
ENDCASE
Allerdings denke ich, dass es schwierig ist, aus dem zweiten Thread den ersten zu überwachen, da Du zwei Event-Loops brauchst. Eventuell kannst Du die Abfrage ja in den Event-Loop des ersten Threads einbauen.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Thread-Programmierung

Beitrag von Tom »

Warum überhaupt die Überwachung in einem gesonderten Thread? Einfach im Eventhandler die Zeit stoppen; wenn innerhalb von x Sekunden nichts passiert, also kein Event eintritt, schließt er, feddisch.
Herzlich,
Tom
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread-Programmierung

Beitrag von UliTs »

Hallo Hubert, hallo Georg,

vielen Dank für Eure Antworten.
Da ich nach einer allgemeinen Lösung suche, funktionieren meines Erachtens beide Vorschläge nicht:
-
Bei Dir, Hubert, müsste ich jede Getlist-Variable Thread 2 übergeben.
Bei Dir, Georg, brauche ich Zugriff auf die Eventloop. Den habe ich leider nicht... Allerdings kann ich mittels PostAppEvent ja vielleicht auch direkt das ESC-Zeichen in die Event-Loop schreiben.
Dabei stellt sich die Frage: wie komme ich an die Thread-Variable des Haupt-Threads ran?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread-Programmierung

Beitrag von brandelh »

Hi,

das aktuelle Thread-Objekt: ThreadObject() - Ermittelt das Thread-Objekt, das den aktuellen Thread verwaltet

Bei TOMs Vorschlag die Eventloop damit zu beauftragen hat man die größte Kontrolle.

Warum da meinst, diese übergeben zu müssen, ist mir nicht klar, in einem Programm das nur den Hauptthread hat,
gibt es nur eine, bzw. man ruft eine Funktion auf, die diesen Loop enthält.

Diese Funktion kann man einmal erstellen und dann einfach kopieren (oder in DLL auslagern ?).
Ich nutze eine solche Funktion um in schnellen Schleifen ab und an 1/100 Zeit an den Eventloop zu geben (Abbruch über GUI Button bzw. Anzeige von GUI Änderungen ...):

*-----------------------------------------------------------------------------

Code: Alles auswählen

FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1:=nil, mp2:=nil, oXbp:=nil

   DEFAULT nSeconds to 0                     // Standard ist endlose Ausführung

   nBisSeconds := seconds() + nSeconds

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
              * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_F1 .and. HelpObject()==NIL
              * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
              ShowNoHelp()  // in ANW_MENU.PRG
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0 .and. nBisSeconds < seconds() // nur wenn keine endlose Ausführung
         exit
      endif
   ENDDO
return nil
du müsstest hier anpassen: case nEvent = xbe_None * nichts tun ist hier Standard
Gruß
Hubert
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Thread-Programmierung

Beitrag von UliTs »

Hallo Tom, Hubert, Georg,

danke für Eure Tipps.
Ich dachte schon, ich hätte die Lösung:

Code: Alles auswählen

PostAppEvent( xbeP_Keyboard/*nEvent*/,chr(27)/*mp1*/,/*mp2*/,ThreadObject()/*oXbp*/ )
Leider kommt aber die folgende Fehlermeldung:
  • Betriebssystem : Windows XP 05.01 Build 02600 Service Pack 3
    ------------------------------------------------------------------------------
    oError:args :
    -> VALTYPE: N VALUE: 1048580
    -> VALTYPE: C VALUE:
    -> VALTYPE: U VALUE: NIL
    -> VALTYPE: O CLASS: thread
    oError:canDefault : N
    oError:canRetry : N
    oError:canSubstitute: J
    oError:cargo : NIL
    oError:description : Objekt nicht angemeldet
    oError:filename :
    oError:genCode : 103
    oError:operation : postAppEvent
    oError:osCode : 0
    oError:severity : 2
    oError:subCode : 4207
    oError:subSystem : BASE
    oError:thread : 1
    oError:tries : 0
Ich kann mir den Luxus leisten und bei Time Out das Programm komplett beenden, was ich jetzt einfach (aus Zeitmangel) mache :-) .
Tom, gibt es eine Möglichkeit bei einem Hybridfenster die Eventloop zu beeinflussen?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread-Programmierung [Erledigt]

Beitrag von brandelh »

Hi,

ein schönes Quit in Ehren ... aber sollte man vorher nicht erst alle Threads schließen ... :?

Bei deinem Beispiel oben fällt mir auf, dass du im Thread selbst das ThreadObject() abfragst,
du solltest aber damit eigentlich vor dem Thread-Start den Main Thread abfragen und als Parameter an den Überwachungsthread übergeben.
Zudem sollte man wenn man schon einen Keyboard Event sendet, diesen nicht an einen Thread, sondern an das Control oder ein Fenster senden.

ein Quit ist sicher einfacher :D
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Thread-Programmierung [Erledigt]

Beitrag von Tom »

aber sollte man vorher nicht erst alle Threads schließen
Definiere: Sollte. :wink:

Man muss nicht. Eine Applikation, die diverse Module in Threads öffnet/anzeigt, kann auch mit QUIT beendet werden, ohne dass vorher alle Threads "geschlossen" werden.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Thread-Programmierung [Erledigt]

Beitrag von brandelh »

Tom hat geschrieben:
aber sollte man vorher nicht erst alle Threads schließen
Definiere: Sollte. :wink:

Man muss nicht. Eine Applikation, die diverse Module in Threads öffnet/anzeigt, kann auch mit QUIT beendet werden, ohne dass vorher alle Threads "geschlossen" werden.
schön das zu wissen, ich meine in der Anleitung stand was von syncronisieren, kann aber sein, dass das nur beim weiteren Betrieb nötig ist ... ich mache nicht soviel mit Threads :D
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Thread-Programmierung [Erledigt]

Beitrag von Tom »

Hallo, Hubert.

Man sollte natürlich grundsätzlich bei/vor jedem QUIT prüfen, ob kritische Prozesse laufen, deren nicht ordnungsgemäße Beendigung zu Problemen führen kann, aber ansonsten ist ein Thread als simpler Prozess zu betrachten, der halt parallel zu anderen läuft. Und all diese Prozesse werden meiner langjährigen Beobachtung nach problemlos beendet, wobei ich jetzt auch nicht so wirklich wüsste, welche Probleme ein von außen beendeter Thread generieren sollte, die nicht auch bei einer SDI-Applikation an gleicher Stelle auftreten könnten. Wenn in der App etwas geschieht, das geflissentlich überhaupt nicht abgebrochen werden sollte, muss man entsprechende Maßnahmen ergreifen. Man wird den Anwender allerdings niemals davon abhalten können, einfach den Netzstecker zu ziehen.

Die Synchronisation von Threads ist dafür gut, sie aufeinander warten zu lassen. Bei einem QUIT werden aber - hiervon unabhängig - ohnehin alle abgesch(l)ossen.
Herzlich,
Tom
Antworten