periodische Ausführung von Befehlen [ERLEDIGT]

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von Benz »

Hi,

Gibt es eine Möglichkeit periodisch auszufürhen? Und wenn das über die Eventschleife läuft kann mir das jemand vielleicht ein wenig ausfürhlicher erklären :? ?
Ich habe das versucht und bein kläglich gescheitert :D.

Ich habe die folgende Eventschleife benutzt:

Code: Alles auswählen

       DO WHILE nEvent <> xbeP_Quit
                 proc_handle_time(cStartTime)
          nEvent := AppEvent( @mp1, @mp2, @oXbp )
          oXbp:handleEvent( nEvent, mp1, mp2 )

       ENDDO
Ich dachte mir die Procedure würde durch den Einbau in die Eventschleife dauerhaft immer wieder ausgeführt, nur leider wird diese da nur ein einziges mal ausgeführt. Wenn ich aber eine Eventschleife noch davor schalte, also zb. so:

Code: Alles auswählen

       DO WHILE nEvent <> xbeP_Quit

         proc_handle_time(cStartTime)

       ENDDO
Dann produziert das eine Endlosschleife (was ja eigentlich gewollt ist), dann reagiert aber das Programm auch nicht mehr.
In C# wird das so viel ich weiß über Threads gelöst, funktioniert das in Xbase++ ähnlich?

Lg Jens
Zuletzt geändert von Benz am Sa, 28. Mär 2015 15:04, insgesamt 1-mal geändert.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: periodische Ausführung von Befehlen

Beitrag von Martin Altmann »

Moin Jens,
die erste Variante sollte gehen, wenn Du einen Timeoutparameter bei AppEvent() mit angibst!
Ansonsten wäre die von Dir angesprochene Lösung mit Threads besser - schau mal in der Hilfe unter SetTimerEvent() (o.s.ä.)

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: periodische Ausführung von Befehlen

Beitrag von Jan »

Ich hab schon beides gemacht. Wobei mir persönlich die Lösung mit dem Thread sympathischer ist.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

Hi, danke! Ich denke, das hilft mir schon weiter ! :)
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: periodische Ausführung von Befehlen

Beitrag von brandelh »

wenn man es in der Eventschleife macht, muss man zwei Dinge beachten:

1. AppEvent( @mp1, @mp2, @oXbp ) bekommt einen 4. Parameter

AppEvent( @mp1, @mp2, @oXbp,100) würde z.B. spätestens nach einer Sekunde wieder in die Schleife gehen ...
aber bei jedem Event wird die Schleife auch durchlaufen !
Wenn man mit der Maus über das Programm geht, könnten das durchaus 1000 Aufrufe je Sekunde werden !

2. Die eigene Funktion muss sehr schnell wieder beendet werden, sonst "spinnt" das Programm (die Bedienung ist stark verzögert).

All diese Überlegungen kann man vergessen, wenn man es mit einem Thread erledigt.
SetTimerEvent() ist z.B. eine einfache Methode so etwas zu implementieren. Dort gibt es auch ein Beispiel für die Sekundenanzeige ;-)
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: periodische Ausführung von Befehlen

Beitrag von Jan »

Ich mach sowas in einem Thread normalerweise mit :setIntervall()

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

Wenn ich den Thread benutze, muss ich da dann irgendetwas beachten? Ich habe nämlich im Moment das Problem, dass ich außerhalb des Thread eine Datenbank per USE
aufrufe. Diese kann ich dann aber innerhalb des Threads nicht verwenden. Muss ich diese dann einfach dort wieder mit USE öffnen? Oder kann das zu Berechtigungsproblemen fürhen?
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: periodische Ausführung von Befehlen

Beitrag von brandelh »

Jeder Thread muss normalerweise seine eigenen Dateien öffnen, das ist dann genauso wie wenn zwei Rechner oder zwei Programme auf eine Datei gemeinsam zugreifen,
also SHARED !
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

OK, das heißt wenn ich den Thread die Datenbank neu öffnen lasse, beeinträchtigt das die den Rest nicht, super, danke :!:
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

Hi, ich habe jetzt ein neues Problem. Und zwar würde ich gerne 2 solche Abfragen durchführen, weil die eine für Import und die andere für Export von Dateien zuständig ist.
Das Zeitintervall soll allerdigns verschieden sein, deshalb kann ich die beiden Codeblöcke nicht in ein SetTimerEvent packen. Mein Problem ist jetzt, wenn ich 2 davon benutze und hitnereinandere in der Main schreibe,
dann überschreibt das zweite das erste. Das heißt das erste wird einmal ausgeführt, dann das zweite und dann periodisch immer nur noch das zweite mit dem angegeben Intervall.

Code: Alles auswählen

       nAbfrageIntervall := ZEITEINS->ZEITIMP * 100
       SetTimerEvent( nAbfrageIntervall , {|| proc_verzeichnisabfrage(cSearchPath,cImportPath) }  )


       nArtikelIntervall := ZEITEINS->ZEITEXP * 100 // *100: 100tel Sekunden, *60: Minuten, *1 Min
       SetTimerEvent( nArtikelIntervall, {|| proc_artikel_export(cExportPath) })
Das hier:

Code: Alles auswählen

SetTimerEvent( nArtikelIntervall, {|| proc_artikel_export(cExportPath) })
überschreibt also praktisch das erste.

Habt ihr eine Möglichkeit wie man das umgehen kann?
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Werner_Bayern »

Jan hat geschrieben:Ich mach sowas in einem Thread normalerweise mit :setIntervall()

Jan
mach es einfach wie Jan geschrieben hat, da bist Du flexibler. SetTimerEvent() kann nur 1x benutzt werden, jeder Neuaufruf überschreibt die bish. Einstellung.
Dürfte intern nichts anderes sein als ein Thread mit setIntervall.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

Ok, das funktioniert jetzt, danke!
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen

Beitrag von Benz »

Also hier die Lösung:

Code: Alles auswählen

LOCAL oThread1 := Thread():new()
LOCAL oThread2 := Thread():new()

oThread1:start ({|| proc_1(param1,param2) })
oThread1:setInterval(1000) // 10 * 100 (weil 1/100 sekunden) -> also 10 Sekunden

oThread2:start ({|| proc_2(param1,param2) })
oThread2:setInterval(2000) // 20 * 100 (weil 1/100 sekunden) -> also 20 Sekunden
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von Werner_Bayern »

:thumbup:
es grüßt

Werner

<when the music is over, turn off the lights!>
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von Benz »

Dazu hab ich jetzt ein kleines Problemchen.
Und zwar muss ich ja jedes Mal wenn der Thread aufgerufen wird, die Datenbanken mit USE aufmachen.
Jetzt bekomm ich aber irgendwann einen Fehler im Programm. Das Programm ruft jede Minute den Thread auf und führt ihn aus, dann bekomme ich irgedwann den Fehler (das Programm läuft über Nacht):
"Syntax error in macro expression" und darunter "DbUseArea". Die betroffene Zeile verweist auf den USE Befehl der ersten Datenbank in dem Thread.
KAnn es sein, dass ich die Datenbanken zu oft aufgemacht habe? Muss ich Sie evtl. wieder schließen in jedem Thread?
Oder muss ich den Thread vielleicht automatisch schließen oder so ähnlich? Ich dachte eigentlich das passiert sowieso,wenn der Code des Threads durchgelaufen ist.

Viele Grüße

Jens
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von Werner_Bayern »

Servus Jens,

wenn Du in einem Thread Datenbanken öffnest, solltest Du diese auch in diesem Thread wieder schließen, ansonsten bleiben so offen, auch wenn der Thread beendet wird. Ein Thread ist ja gekapselt, fast wie eine extra exe. Die DBFs werden in einem extra Workspace geöffnet.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von Benz »

Ok, danke, dann sollte das meine Probleme lösen, hoffe ich doch mal! :D
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: periodische Ausführung von Befehlen [ERLEDIGT]

Beitrag von AUGE_OHR »

hi,

wenn du nur "einfache" Sachen machen willst mit Thread() geht das noch mit "prozeduralem" Code aber damit hast du keinen Zugriff auf einige Methoden die einer Subclass vorbehalten sind.
:atStart( [<xParamList,...>] ) --> NIL
hier würde man z.b. die DBF öffnen
:atEnd( [<xParamList,...>] ) --> NIL
und hier schliessen
:execute()
hier steht nun dein eigentlicher Code
und dann gibt es noch das Thema
:synchronize( <nTimeOut> ) --> lSuccess
p.s. bei Threads und DBF sollte man in der DBESYS die Konstanten DBFDBE_LIFETIME bzw. FOXDBE_LIFETIME auf 0 setzten
gruss by OHR
Jimmy
Antworten