Timer trotz versteckter/ausgeblendeter Form (Hide) weiterlaufen lassen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Timer trotz versteckter/ausgeblendeter Form (Hide) weiterlaufen lassen

    Hallo liebe Community,

    ich möchte gerne eine Programm in den Systemtray minimieren, also ein NotifyIcon einblenden und die Form an sich dann mit "ShowInTaskbar = False" und "Hide()" verstecken, sodass die Form nicht mehr sichtbar ist, auch nicht, wenn man ALT + TAB drückt. Davor möchte ich gerne einen Timer starten, der bestimmte Aktionen ausführt (in meinem Fall prüft dieser auf neue, ungelesene E-Mails). Das funktioniert soweit auch alles bestens, wenn die Form sichtbar ist.

    Sobald ich die Form jedoch mit "Hide()" verstecken lasse, da das E-Mail Benachrichtigungsprogramm natürlich im Hintergrund nicht sichtbar laufen soll (nur das NotifyIcon im Tray ist sichtbar), ist der Timer gestoppt bzw. pausiert und läuft nicht weiter. Das ist bei einem E-Mail Benachrichtigungsprogramm natürlich genau das, was ich eigentlich brauche - der Timer soll auch dann weiter laufen, wenn die Form versteckt ist. Ich habe auch schon versucht, den Timer nach dem Aufruf von "Hide()" noch einmal erneut zu starten, aber das funktioniert auch nicht. Sobald ich das Programm (in meinem Fall mit einem Doppelklick auf das NotifyIcon) wieder sichtbar mache, läuft der Timer wieder weiter. Das gleiche Problem tritt übrigens auch bei einem asynchronen BackgroundWorker auf.

    Gibt es eine Möglichkeit, den Timer auch dann laufen zu lassen, wenn die Form mit "Hide()" versteckt ist oder gibt es eine andere Möglichkeit, die Form zu verstecken? Nur mit "ShowInTaskbar = False" oder auch mit "ShowInTaskbar = False" und "Opacity = 0" wäre es nicht optimal, da man das Programm über ALT + TAB weiterhin sehen kann. Ich würde mich sehr über Antworten und mögliche Lösungsvorschläge freuen, vielen Dank im Voraus!



    Gruß
    Thomas
    Willkommen im Forum. :thumbup:
    Verstecke die Form nicht, mach sie mit .Opacity = 0 durchsichtig.

    Zitat entfernt. ~Thunderbolt
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @RodFromGermany
    Vielen Dank für deine Antwort! Ich habe diese Alternative bereits probiert und sie funktioniert soweit auch, jedoch stört es mich, dass das Programm dann noch via ALT + TAB sichtbar ist, was ich auch geschrieben habe. Ich möchte, dass das Programm bzw. die Form komplett versteckt ist, so, wie es die Hide-Methode machen würde - nur ohne Pausieren oder Stoppen des Timers. Ist das irgendwie möglich? Durch eine Google-Suche habe ich leider keinerlei passende Möglichkeiten gefunden.

    SolusVM schrieb:

    Nur mit "ShowInTaskbar = False" oder auch mit "ShowInTaskbar = False" und "Opacity = 0" wäre es nicht optimal, da man das Programm über ALT + TAB weiterhin sehen kann.


    Zitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Try this:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Me.Hide()
    3. Timer1.Interval = 5000
    4. Timer1.Start()
    5. End Sub
    6. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    7. Timer1.Stop()
    8. Me.Show()
    9. End Sub


    Zitat entfernt. ~Thunderbolt
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @RodFromGermany
    Vielen Dank für deine Antwort! Ich habe es mit dem erneuten Start des Timers nach dem Aufruf von "Hide()" bereits versucht, leider ohne Erfolg. Auch mit einem Setzen des Intervalls, gefolgt von einem Start des Timers funktioniert das Ganze leider nicht.

    SolusVM schrieb:

    Ich habe auch schon versucht, den Timer nach dem Aufruf von "Hide()" noch einmal erneut zu starten, aber das funktioniert auch nicht.


    Zitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @SolusVM
    Mein Code funktioniert, dieser auch:
    Der Timer der unsichtbaren Form schaltet eine weitere Form visible und hide.
    Offensichtlich ist Dein Code falsch.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private dlg As Form2 = New Form2
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. Me.Hide()
    5. dlg.Show()
    6. Timer1.Interval = 2000
    7. Timer1.Start()
    8. End Sub
    9. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    10. dlg.Visible = Not dlg.Visible
    11. End Sub
    12. End Class
    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!
    @Thunderbolt
    Vielen Dank für deine Antwort! Ich gehe alle Posts chronologisch durch und habe das, was RodFromGermany geschrieben hat, ausprobiert. Anschließend habe ich dazu eine Rückmeldung in Form einer Antwort gegeben. Danach habe ich bis jetzt gerade das ausprobiert, was du mir geschrieben hast und was jetzt funktioniert. Anschließend, also jetzt, gebe ich wieder eine Rückmeldung in Form einer Antwort. Ich probiere nicht alles, was hier gepostet wurde, nacheinander aus und schreibe am Ende dann die Antworten sondern probiere alles chronologisch aus und schreibe nach jedem Versuch eine entsprechende Antwort an den Post-Ersteller.

    Ich habe nun manuell einen Timer über System.Threading.Timer definiert (mit AutoResetEvent, TimerCallback usw.) und dieser funktioniert nun. Über eine kleine Methode rufe ich threadübergreifend eine Methode aus meinem Haupthread auf und dieses ruft die E-Mails ab. Wenn ich das Programm nun in den Systemtray minimiere (mit "ShowInTaskbar = False" und "Hide()"), läuft dieser Timer weiter und ruft auch im Hintergrund meine E-Mails ab. Vielen Dank für den Vorschlag!

    Zitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Ich hab 3 Anmerkungen:
    1) ähm, wenn man einen Threading-Timer nimmt, braucht man aber kein AutoResetEvent.
    Ein AutoResetEvent blockiert den aktuellen Thread, also das ist ziemlich unfreundlich zu den Resourcen. Da wird also offsichtlich was falsch angewandt.



    2) Ich halte einen Threading-Timer auch für nicht sinnvoll, wenn dessen Ticks dann doch in den MainThread transferiert werden müssen. Dann kann man auch einen Winforms-Timer nehmen, bei dem ist der Thread-Transfer quasi eingebaut.



    3) Hast du übrigens mal den SpeicherVerbrauch gecheckt?