Timer als Hintergrundprozess zum Ausführen von Code zu bestimmten Zeiten

  • VB.NET

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    Timer als Hintergrundprozess zum Ausführen von Code zu bestimmten Zeiten

    Hallo Ihr Experten,

    ich habe eine Frage zur Verarbeitung von Timern in einer Windows Forms Application.
    Auf der Form hat man die Möglichkeit für die einzelnen Wochentage eine Uhrzeit einzustellen und eine "Aktion" auszuwählen.
    Ich muss nun irgendwie permanent die Uhrzeit prüfen und wenn es mit dem Eintrag der Textbox übereinstimmt, je nach gewählter Aktion eine bestimmte Stelle Code ausführen.
    Also im Grunde wie ein "Wochenschaltkalender", der z.B Montags um 8:23 irgendetwas macht.

    Wie kann ich so etwas realisieren, damit es auch nachher zuverlässig funktioniert? Es muss ja irgendwie ein Hintergrundprozess unabhängig von der Form gestartet werden?
    Hier im Forum habe ich ein paar solcher Ansätze gelesen, die aber dann doch in anderen Lösungen geendet sind.

    Bin dankbar für jede Hilfe!!

    Gruß,
    Mark


    *Topic verschoben* ~NoFear23m

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Nofear23m“ ()

    @mhoeftx Am besten ist es, Du machst Dir eine Liste mit den Datümmern+Zeiten, zu denen es ticken soll.
    Die wird nach DateTime sortiert.
    Im Prinzip kannst Du Dir einen Minuten-Timer (System.Threading.Timer) machn, und zu jedem Tick siehst Du nach, ob für die nächsten Minute ein Eintrag besteht.
    Wenn Nein - Raus.
    Wenn Ja - Meldung an eine GUI machen (per Invoke), die dann was anzeigt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Moin,

    aus der Toolbox einen Timer auf die Form ziehen.

    Zu reinen Anzeige der Aktuellen Uhrzeit würde ich z.B. noch ein Label platzieren, welches die aktuelle Uhrzeit anzeigt.

    Dann im Form_Load Ereignis

    VB.NET-Quellcode

    1. Timer1.Enabled = True
    2. Timer1.Interval = 1000
    3. Label1.Text = DateTime.Now.ToLongTimeString()


    Dann in der Form unten auf Timer1 doppel Klicken.

    Dann folgendes:

    VB.NET-Quellcode

    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2. Label1.Text = DateTime.Now.ToLongTimeString()
    3. 'Hier kannst du jetzt die aktuelle Uhrzeit abfragen und nach Übereinstimmung mit deinen Textboxen abfragen. Wenn gleich dann Code ausführen
    4. End Sub


    Hier sei allerdings gesagt, das dein Programm dazu immer laufen bzw. gestartet sein muss. Eine Alternative wäre hier vielleicht ein Dienst.

    Holistiker schrieb:

    Timer1.Interval = 1000

    Hmmmm - Dann wird der Code 60x ausgeführt. Der Ansatz von @RodFromGermany mit einer Minute ist hier denke ich besser. Wobei ich bei sowas wie 50 Sekunden wäre da die Timergeschichte nicht immer 100% genau ist da Windows kein Echtzeitsystem ist und es bei genau einer Minute zu einem "überspringen" kommen könnte.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Wie wär es denn stattdessen mit einer Berechnung? Dass der Timer sein Intervall so einstellt, dass das nächste Ereignis angepeilt wird. Man sagt dem Programm: »Zeige mir einen Text 21:23:00.« Zu diesen Zeitpunkt ist es 20:45:48. Dann rechnet man eben die Zeitdifferenz in ms aus und stellt das als Timer-Intervall ein.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    jo, das wäre annähernd performance-optimal, weil so ein Timer nur tickt, wenn nötig.
    Aber sehr nötig ist sone Optimierung nicht, also wenn ein Timer alle Minute mal tickt, nur um festzustellen, dass nix zu tun ist - frisst kein Brot.
    Übrigens das Intervall für eine Minute wäre schlicht auf 60000 einzustellen.

    anneres Problem könnte sein: was ist, wenn der Rechner mal runtergefahren wird, oder sonst ein Grund, dass das Proggi ausgeschaltet ist?
    Vielen Dank für Eure Antworten!
    Da merke ich gleich wieder, dass ich mir über einige Dinge noch gar keine Gedanken gemacht habe.
    Fakt ist auf jeden Fall, es kann vorkommen, dass sowohl Applikation als auch PC neu gestartet werden.
    Ich überlege deshalb, ob man es vielleicht etwas anders angehen sollte und nicht direkt auf den Zeitpunkt prüft sondern auf einen Zeitraum?!?

    Beispiel: Wer Montags um 8:23 etwas einschaltet, schaltet es in meinem Fall irgendwann im laufe des Tages auch wieder aus.
    So dass man vielleicht sagen könnte, wenn der Zeitraum zwischen 8:00 und 19:00 liegt muss es eingeschaltet sein, wenn nicht, dann eben aus.
    So könnte man doch auch das Programm neustarten usw oder?

    Ich würde dann also einen Timer mit Intevall von 1 Minute prüfen lassen ob Startzeit < DateTime.Now < Endzeit ist ?
    Dann wäre nur das Problem wenn die Endzeit nach 23:59 liegt aber ansonsten wäre es in diese Richtung am praktikabelsten oder was meint ihr?
    Dann sollte erstmal geklärt werden, was genau denn passieren soll. Soll zu einem bestimmten Zeitpunkt ein Hinweis angezeigt werden? Ein Programm gestartet werden? Eine Permanentüberwachung dazugeschaltet werden? Solange wir das nicht wissen, ist nicht vernünftig zu sagen, was für Dich nun das beste wäre.
    Denn zwischen dem Programmcode,

    mhoeftx schrieb:

    der z.B Montags um 8:23 irgendetwas macht.
    und

    mhoeftx schrieb:

    Wer Montags um 8:23 etwas einschaltet, schaltet es in meinem Fall irgendwann im laufe des Tages auch wieder aus.
    (was immer das auch für eine Aussage zum Programmverhalten darstellen soll), gibt es doch einen inhaltlichen Unterschied.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ich gebe dir vollkommen recht, ich hätte ein paar Worte dazu spendieren sollen.

    In meinem Fall ist es tatsächlich so, dass es täglich zwei Schaltzeiten gibt.
    Morgens wird ein bestimmter Teil Code ausgeführt und im Laufe des Tages ein anderer.
    Ich schalte damit Relaisausgänge an einem I/O Modul.
    Deshalb auch meine Ausdrucksweise "Ein" und "Aus".

    Da ich noch nie mit Timern gearbeitet habe und nicht wusste, wo ich ansetzen muss,
    habe ich es zunächst nicht als einen Zeitraum betrachtet, sondern als zwei einzelne Zeiten an denen irgendein Code ausgeführt werden soll.

    mhoeftx schrieb:

    wenn die Endzeit nach 23:59 liegt
    ist das auch kein Problem, denn da fängt der nächste Tag mit 0:00 Uhr an.
    Wenn der Rechner aus ist, kann nix gemeldet werden.
    Wenn das Programm beendet wird, kann nix gemeldet werden.
    Wohl aber kannst Du eine Warnung ausgeben, wenn das Programm vom User beendet wird und nachfragen, ob das gewollt ist.
    Vielleicht denkst Du zunächst mal nach und erklärst mir den Unterschied zwischen
    - 12 Uhr und
    - 12 Stunden,
    dann sehen wir weiter.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Vielleicht denkst Du zunächst mal nach und erklärst mir den Unterschied zwischen
    - 12 Uhr und
    - 12 Stunden,
    dann sehen wir weiter.


    Ehrlich gesagt weiß ich nicht worauf du hinaus willst.

    Mir ist klar, dass es nicht funktioniert wenn Rechner oder Programm aus sind!
    Auch ist mir bewusst, dass ich den User beim Schließen darauf hinweisen kann!

    Darum geht es hier aber doch überhaupt nicht.

    Ich habe im vorherigen Post den Gedanken gehabt, dass ich den Zeitraum prüfe z.B

    Quellcode

    1. Startzeit < DateTime.Now < Endzeit


    Dies Funktioniert ja nicht, wenn z.B an einem Montag eine Zeit von 19:00 bis 00:30 angegeben wird.

    Gehe ich noch einen Schritt weiter: Es liegt irgendein Problem vor und das Programm läuft eben mal nicht. z.B von 00:00 bis 01:00 Uhr.
    Dann sollte ja z.B der verpasste Schaltvorgang von 0:30 nachgeholt werden, weil ich mich ja in einem Zeitraum befinde, wo mein Relais nicht geschaltet sein darf.
    Nächster Zeitraum für "An" wäre dann meinetwegen erst wieder am nächsten Tag von 08:00 bis 19:00
    Na dann, nur zu. Im Sinne von:

    VB.NET-Quellcode

    1. Public Enum RelaisStatus
    2. On
    3. Off
    4. End Enum
    5. '...
    6. If CurrentRelaisStatus = RelaisStatus.Off AndAlso Startzeit < DateTime.Now AndAlso DateTime.Now < Endzeit Then
    7. CurrentRelaisStatus = RelaisStatus.On
    8. ElseIf CurrentRelaisStatus = RelaisStatus.Off AndAlso (DateTime.Now < Startzeit OrElse DateTime.Now > Endzeit) Then
    9. CurrentRelaisStatus = RelaisStatus.Off
    10. End If
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    mhoeftx schrieb:

    Ehrlich gesagt weiß ich nicht worauf du hinaus willst.
    Das ist eine einfache aber wichtige Verständnisfrage.
    Beantworte sie einfach.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Worauf @RodFromGermany hinaus möchte ist wahrscheinlich der Unterschied zwischen der Uhrzeit (12 Uhr) und der Zeitspanne (12 Stunden).
    Datetime und Timespan.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    @Akanel Petze. X(
    Nun ist leider der Lerneffekt weg.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Weisst du, vor geraumer Zeit war ich selbst an dem Punkt, und Du hast mir die selbe Frage gestellt.
    Der Lerneffekt kam bei mir aber erst mit dem Wissen das es 2 verschiedene Datentypen sind und wie man damit arbeitet.
    Desweiteren schrieb der TE das er nicht weiss worauf du hinaus möchtest. Es war nur als Hilfe gedacht.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.

    Akanel schrieb:

    Es war nur als Hilfe gedacht.
    Da hättest Du ja auch mich antworten lassen können.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ErfinderDesRades schrieb:

    Was ist der Unterschied zw. 12 Uhr und 12 Stunden?

    Ist das eine nicht ein Zeitpunkt und das andere eine Zeitspanne? Aber das hat eh @Akanel bereits erwähnt. Sind im Grunde ja wirklich zwei verschiedene "Dinge".

    Aber nichts desto trotz Hilft es dem TE vermutlich nicht wirklich.

    @mhoeftx, mach dir wirklich mal Gedanken was deine Applikation alles können MUSS. Weitere Features kannst du nachimplementieren, aber Gewisse Dinge sollten vorab geklärt werden. Was ist ein musthave und was ein nice to have. Dann würde ich hier mal allgemein Nachfragen (Anhand der Liste) wie hier die Leute vorgehen würden. Evtl. kann die Windows-Aufgabenplanung dir hier behilflich sein, evtl. solltest du einen Dienst schreiben usw.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##