Dynamisch erstellten Timer zerstören

  • VB.NET
  • .NET 3.5

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    Dynamisch erstellten Timer zerstören

    Hallo zusammen,

    ich habe nach 5 Stunden INet suche nichts brauchbares finden können. Zerstören von Controls ja, aber speziel Timer leider nichts.
    Wie kann ich einen dynamischen Timer finden und zerstören?

    VB.NET-Quellcode

    1. Private Sub timer_tick(ByVal sender As Object, ByVal e As EventArgs)
    2. MsgBox("Test")
    3. End Sub
    4. Private Sub form_load(ByVal sender As Object, ByVal e As System.EventArgs)
    5. Dim t As New System.Windows.Forms.Timer
    6. t.Interval = 10000
    7. AddHandler t.Tick, AddressOf timer_tick
    8. Me.components.Add(t)
    9. t.Start()
    10. End Sub
    11. Private Sub form_disposed(ByVal sender As Object, ByVal e As System.EventArgs)
    12. 'hier versuche ich den Timer zu zerstören, geht leider nicht
    13. for each t as timer in Sender.components
    14. t.dispose()
    15. next
    16. End Sub


    bitte um Hilfe

    Danke, Gruß Crazy

    crazycrash schrieb:

    VB.NET-Quellcode

    1. Dim t As New System.Windows.Forms.Timer
    Mach da zwei Zeilen draus.
    In der Klasse:

    VB.NET-Quellcode

    1. Dim WithEvents t As System.Windows.Forms.Timer
    Allerdings kannst Du dann auch den Timer im Designer auf die Form ziehen.
    In der Prozedur:

    VB.NET-Quellcode

    1. t = System.Windows.Forms.Timer

    Und dann kannst Du ihn in einer (anderen) Prozedur zerstören:

    VB.NET-Quellcode

    1. t.Dispose()
    2. t = Nothing
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    danke für die schnelle antwort

    das geht so nicht. der timer ist dynamisch, also ohne klasse, ohne globale Deklaration, ohne auf die form ziehen.
    so wie ich das verstanden habe, ist withevents global.(korrigiere mich wenn ich falsch liege)
    ich erzeuge und starte den timer in einer dynamischen form "form_load" und zerstöre diesen bei "form_dispose"

    meine Problem ist diesen timer in der Prozedur "form_dispose" zu identifizieren bzw. auf zu listen.

    sry wenn ich etwas missverstehe
    @crazycrash Dann muss in der dynamischen Form die Deklaration des Timers in die Klasse und die Instanziierung und die Zugriffe in entsprechende Prozeduren.
    Warum verwendest Du keine im Designer designete Form als dynamischen Form?
    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Dann muss in der dynamischen Form die Deklaration des Timers in die Klasse und die Instanziierung und die Zugriffe


    ich dachte das habe ich hiermit getan?:

    VB.NET-Quellcode

    1. Private Sub form_load(ByVal sender As Object, ByVal e As System.EventArgs)
    2. Dim t As System.Windows.Forms.Timer
    3. AddHandler t.Tick, AddressOf timer_tick
    4. Me.components.Add(t)
    5. t.Start()
    6. End Sub


    wie kann ich jetzt diesen timer aus fomr_load bei form_dispose finden und zerstören. am einfachsten wäre das hier:

    VB.NET-Quellcode

    1. Private Sub form_disposed(ByVal sender As Object, ByVal e As System.EventArgs)
    2. for each t as timer in sender.controls
    3. t.dispose()
    4. next
    5. End Sub

    da aber der timer kein control ist, geht es nicht einfach :) so
    Hi
    normalerweise sollte man wohl nur einen einzigen Timer für dieselbe Aufgabe verwenden. Was erledigst du mit dem timer_tick?

    Eine Lösung zumindest des Problems wäre (d.h. nicht, dass es eine gute ist!), die Timer in einer Liste zu behalten oder sich selbst zerstören zu lassen.
    Ersteres ginge bspw. über eine List(Of Timer) oder LinkedList(Of Timer) oder Dictionary(Of TKey, Timer) oder was auch immer, in die du per Add die Timer einfügst. Im Falle des Dictionarys benötigst du noch einen Typ für TKey, der angibt, auf welchen Timer du zugreifst. Vergiss nicht, gelöschte Timer aus der Liste zu entfernen.
    Zweiteres geht, indem du vor jeden Tick eine Überprüfung setzt, die überprüft, ob der Timer noch laufen sollte und dann über DirectCast(sender, Timer).Dispose() den Timer löscht und den Vorgang überspringst.

    Auch wenn die Lösungen funktionieren, sind sie nicht unbedingt gut, daher würd' ich mich freuen, wenn du die erste Frage beantwortest. ;)

    Übrigens: System.Windows.Forms.Timer sind, außer in Komponenten (auch Controls sind Komponenten), zu vermeiden, da sie eben System.Windows.Forms voraussetzen und zudem eine Anwendung, die eine Nachrichtenschleife besitzt. Stattdessen gibt es z.B. System.Threading.Timer.

    Viele Grüße
    ~blaze~
    also ich habe nur einen timer.

    also grob die Funktion:
    1. form "frm" wird dynamisch erstellt

    VB.NET-Quellcode

    1. Dim frm As New Form
    2. AddHandler frm.Load, AddressOf form_load
    3. AddHandler frm.Disposed, AddressOf form_disposed

    2. form "frm" generiert dynamisch beim Event "frm_load" einen timer "t" und das passende tick Event und startet diesen

    VB.NET-Quellcode

    1. Private Sub form_load(ByVal sender As Object, ByVal e As System.EventArgs)
    2. Dim t As System.Windows.Forms.Timer
    3. t.Interval = 10000
    4. AddHandler t.Tick, AddressOf timer_tick
    5. Me.components.Add(t)
    6. t.Start()
    7. End Sub

    3. beim timer "t" tick wird eine Datenbank abfrage gemacht

    VB.NET-Quellcode

    1. Private Sub timer_tick(ByVal sender As Object, ByVal e As EventArgs)
    2. 'DB Abfrage usw......
    3. End Sub

    4.beim zerstören der form "frm" mit dem Event "frm_dispose" soll der timer "t" aufhören zu ticken bzw. mit zerstört werden

    VB.NET-Quellcode

    1. Private Sub form_disposed(ByVal sender As Object, ByVal e As System.EventArgs)
    2. 'hier muss die Zerstörung vom timer "t" rein
    3. End Sub


    es funktioniert alles bis auf die Zerstörung vom timer....wie mache ich das am besten?

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

    crazycrash schrieb:

    hiermit getan
    Im Prinzip ja.
    Eine Prozedur form_disposed gibt es nicht, Du müsstest Protected Overrides Sub Dispose(ByVal disposing As Boolean) nutzen, ohne AddHandler.
    Hier genügt der Aufruf

    VB.NET-Quellcode

    1. t.Stop()
    2. t.Dispose()
    , wenn der Timer in der Klasse liegt.
    Nimm eine im Designer erstellte Form :!:
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    @RodFromGermany es gibt ein Ereignis Form.Disposed.

    Warum erstellst du den Timer manuell?

    Ansonsten ist der Trick wohl einfach:
    Erstelle einen Timer und eine Liste, die die Daten für die Queries bereithält und führe dann diese Queries im Tick aus. Es wäre übrigens auch möglich, das asynchron zu erledigen, sodass die Form nicht freezt.

    Viele Grüße
    ~blaze~
    @~blaze~

    RodFromGermany schrieb:

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    ist doch in der vom Designer erstellten Form bereits enthalten.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    wenn ich den timer im designer hinzufüge, ist es nicht mehr dynamisch.
    der timer soll zur Laufzeit erzeugt und zerstört werden.
    genau das ist ja das Problem, der timer wird in einer Prozedur erzeugt und in einer anderen zerstört. funktioniert z.B. mit einer TextBox problemlos.

    hier funktionierendes Beispiel:

    VB.NET-Quellcode

    1. private sub formlesView()
    2. Dim frm As New Form
    3. Dim txt1 As New TextBox
    4. frm.Controls.Add(txt1)
    5. AddHandler txt1.Click, AddressOf testClick
    6. end sub
    7. Private Sub testClick(ByVal sender As Object, ByVal e As System.EventArgs)
    8. sender.dispose()
    9. End Sub

    wie realisiere ich das ganze mit einem timer?

    crazycrash schrieb:

    Problem
    Erstell Dir eine Form mit nem Timer und sieh Dir den Code an, den der Designer erzeugt. Stelle diesen nach.
    Das passiert in der Prozedur InitializeComponents() in der Datei FormX.Designer.vb.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Habs jetzt auch noch schnell wissen wollen. Und bei mir funkst es.

    Hab hier 3 Timer und eine davon ist in einer separaten Klasse.

    Bestimmt nicht die Beste Lösung, aber zum Zeigen reicht es bestimmt.

    Freundliche Grüsse

    exc-jdbi
    Dateien
    • TimerTest.zip

      (3,88 kB, 29 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „exc-jdbi“ ()

    hi exc-jdbi,

    danke erstmal.
    klar funktioniert dein Beispiel, so gelöst bekomme ich das auch hin.
    Ich möchte gerne aber auf globale Deklaration verzichten, das ist für mich dann nicht mehr dynamisch zur Laufzeit erstellt.
    Ich teste mal den Vorschlag vom RodFromGermany....
    Ansonsten:
    Bau dir eine (globale) List(Of Timer) pack da alle Timer rein, und wenn die Form dann beendet wird, lauf mit ForEach durch die Liste und dispose alle Timer.
    Post-AGB:
    §1 Mit dem Lesen dieses Posts stimmst du den AGB unverzüglich zu
    §2 Ein Widerruf muss innerhalb von 3 Sekunden nach Lesen des Hauptbestandteil des ersten jemals gelesenen Posts erfolgen
    Abs.1 Die Signatur zählt nicht zum Hauptbestandteil des Posts
    §3 Ein erfolgreicher Widerruf zwingt zu einem Besuch bei einem Hypnotiseur oder Neurochirurg, sodass der gelesene Text aus den Erinnerungen entfernt werden kann
    Abs.1 Die Kosten und Risiken sind jeweils selbst zu tragen

    crazycrash schrieb:

    dynamisch zur Laufzeit



    Oder noch einen Schritt zurück und erstell dir doch gleich ein eigenes TimerControl, wenn du es während der Laufzeit erstellen will'st. Dann kannst du deinen eigenen Timer deinen Bedürfnissen entsprechend anpassen.

    Ich hab die eine Vorlage im Anhang.

    In TimerControl.Designer.vb kannst du folgendes entkommentieren, dann siehst noch genau was gemacht wird im Designer, wenn du z.B. Disposest

    VB.NET-Quellcode

    1. '<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    2. '<System.Diagnostics.DebuggerNonUserCode()> _
    3. '<System.Diagnostics.DebuggerStepThrough()> _


    Freundliche Grüsse

    exc-jdbi
    Dateien
    • TimerTest2.zip

      (4,33 kB, 33 mal heruntergeladen, zuletzt: )
    Es wäre ineffizient, dafür ein eigenes Steuerelement einzuführen. Komponenten sind lightweight, Steuerelemente hingegen bringen wahnsinnig viel Zeug mit. Das lässt sich schon allein an der Zahl der Properties, Events, usw. von Controls feststellen.
    Wie gesagt: Ich würde eine Liste verwenden.

    Viele Grüße
    ~blaze~