Timer stockt

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von nt-software.

    Timer stockt

    Tach,
    ich habe 2 Timer. In einem Timer werden alle 10 Sekunden Informationen von einer MySQL Datenbank (online) in zwei ListView's geschrieben. Der 2. Timer (Interval: 600) blendet eine PictureBox ein und aus. Wenn ich jetzt beide Timer gleichzeitig laufen lasse, stockt der 2. Timer (PictureBox), wenn der 1. Timer gerade dabei ist die ListView zu füllen. Wie kann ich das besser Lösen? Mit einem Backgroundworker? Das habe ich eben probiert, jedoch klappt das mit der MySQL Verbindung nicht richtig. Ist das überhaupt der richtige Weg?
    Hallo nt-software,

    und du wunderst dich ?

    Überleg doch mal
    Dein Timer2 wird alle 600ms ausgeführt.

    Alle anderen Events incl. das was Windows so nebenbei macht, müssten dann in kürzerer Zeit - als eben diese 600ms - ablaufen.

    Wie lange ist denn dein Timer 1 beschäftigt ?
    Hast du das schon einmal gemessen ? (Stichwort: Stoppwatch-Klasse)

    Gruss

    mikeb69
    ChaosBernd:
    Ja, und zwar ist die PictureBox ein Warnblinker-Bild (2 Pfeile wie mans vom Auto kennt), das dann alle 600 ms ein und ausgeblenet wird (dabei noch so ein Klick-Klack-Sound).. Und der Timer1 muss jede 10Sekunden die Liste aktualisieren...

    Sythas:
    Ja, habe ich mir auch schon gedacht. Ich werde es jetzt nochmal versuchen mit dem BGW.

    nt-software schrieb:

    Ja, habe ich mir auch schon gedacht. Ich werde es jetzt nochmal versuchen mit dem BGW.

    Brauchst du nicht, wenn du statt des Windows.Forms.Timer den Timers.Timer nimmt. Denn dessen Event läuft in nem neuen Thread.
    Vorsicht natürlich bei Zugriff auf Controls, wegen threadübergreifendem Vorgang. Also immer schön "invoken" !
    Hi picoflop,
    habe es jetzt mit dem Timers.Timer probiert.

    VB.NET-Quellcode

    1. Imports System.Timers
    2. Private WithEvents MyTimer As New Timers.Timer
    3. Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
    4. Call Meldungen_laden() '< Meine Sub
    5. End Sub


    Wie du schon erwähnt hast klappt das nicht, weil er nicht auf andere Controls zugreifen kann. Jetzt habe ich schon irgendwas mit Delegates gelesen, das versteh ich aber gar nicht. Und was meinst du mit invoken? Kannst mir da ein Beispiel geben?
    Irgendwie will das immernoch nicht.
    Hier mal mein ganzer Code:

    VB.NET-Quellcode

    1. Imports System.Timers
    2. Imports System.Threading
    3. Private WithEvents MyTimer As New Timers.Timer


    VB.NET-Quellcode

    1. Private Sub FMSMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. MyTimer.Interval = 10000
    3. MyTimer.Enabled = True
    4. Dim d As DlgMachwas = AddressOf Meldungen_laden
    5. lstvMeldungen.Invoke(d)
    6. lstvUser.Invoke(d)
    7. End Sub


    VB.NET-Quellcode

    1. Public Sub Meldungen_laden()
    2. Dim vAnzahl As Integer
    3. myData.Reset()
    4. vSQL = "SELECT * FROM tbl_Meldungen"
    5. conn.Open()
    6. myCommand.Connection = conn
    7. myCommand.CommandText = vSQL
    8. myAdapter.SelectCommand = myCommand
    9. myAdapter.Fill(myData)
    10. conn.Close()
    11. vAnzahl = lstvMeldungen.Items.Count
    12. lstvMeldungen.Items.Clear() 'Alle Items löschen
    13. Dim i As Long
    14. For i = myData.Rows.Count - 1 To 0 Step -1
    15. lstvMeldungen.Items.Add(myData.Rows(i).Item(0).ToString).Group = lstvMeldungen.Groups.Item("lstvgEinsaetze")
    16. 'lstvMeldungen.Groups("lstvgEinsaetze").Items.Add.
    17. 'lstvMeldungen.Groups("lstvgEinsatze").Items.Add(myData.Rows(i).Item(0).ToString)
    18. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(9).ToString))
    19. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(9).ToString))
    20. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(1).ToString))
    21. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(1).ToString))
    22. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(2).ToString))
    23. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(2).ToString))
    24. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(3).ToString))
    25. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(3).ToString))
    26. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(4).ToString))
    27. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(4).ToString))
    28. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(5).ToString))
    29. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(5).ToString))
    30. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(6).ToString))
    31. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(6).ToString))
    32. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(7).ToString))
    33. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(7).ToString))
    34. lstvMeldungen.Groups("lstvgEinsaetze").Items(lstvMeldungen.Groups("lstvgEinsaetze").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(8).ToString))
    35. 'lstvMeldungen.Items(lstvMeldungen.Items.Count - 1).SubItems.Add((myData.Rows(i).Item(8).ToString))
    36. Next
    37. If vNeu = True Then
    38. vNeu = False
    39. Else
    40. If lstvMeldungen.Items.Count > vAnzahl Then
    41. tmrTasteBlinken.Start()
    42. If Alarm = True Then
    43. If AlarmTon = 1 Then
    44. If IO.File.Exists(Application.StartupPath & "\Alarm1.wav") Then
    45. My.Computer.Audio.Play(Application.StartupPath & "\Alarm1.wav", AudioPlayMode.Background)
    46. Else
    47. MessageBox.Show("Die Datei ""Alarm1.wav"" konnte nicht gefunden werden!", "Alarm1.wav...", MessageBoxButtons.OK, MessageBoxIcon.Error)
    48. End If
    49. End If
    50. If AlarmTon = 2 Then
    51. If IO.File.Exists(Application.StartupPath & "\Alarm2.wav") Then
    52. My.Computer.Audio.Play(Application.StartupPath & "\Alarm2.wav", AudioPlayMode.Background)
    53. Else
    54. MessageBox.Show("Die Datei ""Alarm2.wav"" konnte nicht gefunden werden!", "Alarm2.wav...", MessageBoxButtons.OK, MessageBoxIcon.Error)
    55. End If
    56. End If
    57. If AlarmTon = 3 Then
    58. If IO.File.Exists(Application.StartupPath & "\Alarm3.wav") Then
    59. My.Computer.Audio.Play(Application.StartupPath & "\Alarm3.wav", AudioPlayMode.Background)
    60. Else
    61. MessageBox.Show("Die Datei ""Alarm3.wav"" konnte nicht gefunden werden!", "Alarm3.wav...", MessageBoxButtons.OK, MessageBoxIcon.Error)
    62. End If
    63. End If
    64. If AlarmTon = 4 Then
    65. If IO.File.Exists(Application.StartupPath & "\Alarm4.wav") Then
    66. My.Computer.Audio.Play(Application.StartupPath & "\Alarm4.wav", AudioPlayMode.Background)
    67. Else
    68. MessageBox.Show("Die Datei ""Alarm4.wav"" konnte nicht gefunden werden!", "Alarm4.wav...", MessageBoxButtons.OK, MessageBoxIcon.Error)
    69. End If
    70. End If
    71. End If
    72. End If
    73. End If
    74. User_laden()
    75. End Sub


    VB.NET-Quellcode

    1. Public Sub User_laden()
    2. myData.Reset()
    3. vSQL = "SELECT UR.ID, UR.Name, UR.Rechte, FZ.Fahrzeug, UR.Verfügbar, UR.Status FROM tbl_User UR, tbl_Fahrzeuge FZ WHERE UR.Fahrzeug = FZ.ID"
    4. conn.Open()
    5. myCommand.Connection = conn
    6. myCommand.CommandText = vSQL
    7. myAdapter.SelectCommand = myCommand
    8. myAdapter.Fill(myData)
    9. conn.Close()
    10. lstvUser.Items.Clear() 'Alle Items löschen
    11. For i = 0 To myData.Rows.Count - 1
    12. '##################If myData.Rows(i).Item(2).ToString = "User" Then 'Nur Users
    13. 'If myData.Rows(i).Item(4).ToString = "Offline" Then 'Wenn Offline
    14. ' lstvUser.Items.Add(myData.Rows(i).Item(1).ToString).Group = lstvUser.Groups.Item("ListViewGroupOffline")
    15. 'Else 'Wenn Online
    16. lstvUser.Items.Add(myData.Rows(i).Item(1).ToString).Group = lstvUser.Groups.Item("lstvgUser")
    17. lstvUser.Groups("lstvgUser").Items(lstvUser.Groups("lstvgUser").Items.Count - 1).SubItems.Add((myData.Rows(i).Item(3).ToString))
    18. '#################End If
    19. 'End If
    20. Next
    21. End Sub


    VB.NET-Quellcode

    1. Private Delegate Sub DlgMachwas()
    2. Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
    3. Meldungen_laden()
    4. End Sub


    Es kommt immer der Fehler wegen dem threadübergreifendem Vorgang.
    Control.Invoke benutzt man, damit eine Methode im Thread des betreffenden Controls ausgeführt wird. Das Timer_Elapsed Event feuert in seinem EIGENEN Thread, also muss man DORT das .Invoke verwenden! In Form_Load macht es keinen Sinn, weil Form_Load ja sowieso schon im GUI-Thread ist und das ist auch der Thread in dem alle Controls liegen.

    VB.NET-Quellcode

    1. Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
    2. Meldungen_laden()
    3. Dim d As DlgMachwas = AddressOf Meldungen_laden
    4. lstvMeldungen.Invoke(d)
    5. lstvUser.Invoke(d)
    6. End Sub


    Klappt leider nicht, und ich weiß nicht wieso... :(

    Er markiert folgende Zeile grün:

    VB.NET-Quellcode

    1. lstvUser.Items.Add(myData.Rows(i).Item(1).ToString).Group = lstvUser.Groups.Item("lstvgUser")


    Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement lstvUser erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

    VB.NET-Quellcode

    1. Private Delegate Sub bling()
    2. Private Sub newbling()
    3. PictureBox1.Visible = Not PictureBox1.Visible
    4. End Sub
    5. Private Sub blingBling()
    6. Dim d As bling = AddressOf newbling
    7. Do While 1 'abbruch Bedingung einfügen oder endlos loop belassen
    8. Threading.Thread.Sleep(600)
    9. If PictureBox1.InvokeRequired Then : PictureBox1.Invoke(d)
    10. Else : PictureBox1.Visible = Not PictureBox1.Visible
    11. End If
    12. Loop
    13. End Sub
    14. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    15. Dim t As New Threading.Thread(AddressOf blingBling)
    16. t.IsBackground = True 'bg thread, da keine daten bearbeitet werden, verhindert exception wenn der gui thread gekillt wird
    17. t.Start()
    18. End Sub


    hi, probiers mal so, vll hast dann kein "stocken" mehr.

    gruss mono
    Das ist meine Signatur und sie wird wunderbar sein!
    Entweder du deklarierst t global oder du buast in die Do While SChleife eine Bedingung ein wie

    Do While KeepRunning

    ..

    Loop


    Und deklarierst Keeprunning Global als Boolean und setzt diese dann ggf auf false.
    Alternativ kannst auch eine andere Abfrage in den Thread bauen.. bissl selber nachdenken hilft ;)

    gruss mono
    Das ist meine Signatur und sie wird wunderbar sein!

    VB.NET-Quellcode

    1. Dim KeepRunning As Boolean


    VB.NET-Quellcode

    1. Private Sub Form_load ...
    2. KeepRunning = False
    3. End Sub


    VB.NET-Quellcode

    1. Private Sub btnBLINKER_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnBLINKER.Click
    2. Dim t As New Threading.Thread(AddressOf blingBling)
    3. t.IsBackground = True
    4. t.Start()
    5. If KeepRunning = False Then
    6. KeepRunning = True
    7. Else
    8. KeepRunning = False
    9. End If
    10. End Sub


    VB.NET-Quellcode

    1. Private Delegate Sub blinkerblink()

    VB.NET-Quellcode

    1. Private Sub newblink()
    2. picBlinker.Visible = Not picBlinker.Visible
    3. End Sub

    VB.NET-Quellcode

    1. Private Sub blingBling()
    2. Dim d As blinkerblink = AddressOf newblink
    3. If KeepRunning = True Then
    4. Do While KeepRunning 'abbruch Bedingung einfügen oder endlos loop belassen
    5. Threading.Thread.Sleep(600)
    6. If picBlinker.InvokeRequired Then : picBlinker.Invoke(d)
    7. Else : picBlinker.Visible = Not picBlinker.Visible
    8. End If
    9. Loop
    10. Else
    11. picBlinker.Visible = False
    12. End If
    13. End Sub


    Ich bekomme bei

    VB.NET-Quellcode

    1. picBlinker.Visible = False

    einen Fehler, wegen dem threadübergreifendem Vorgang.. Aber wieso? Oben wurde picBlinker doch Invoked?!
    Auch wenn ich

    VB.NET-Quellcode

    1. picBlinker.Invoke(d)
    2. picBlinker.Visible = False

    mache, sagt er das gleiche...

    .. Wieso ich picBlinker.Visible = False mache? Weil sonst das picBlinker Visible = True ist wenn man auf den btnBLINKER klickt (wenn man es ausschalten will)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nt-software“ ()

    DU hast scheinbar den Sinn von Invoke nicht verstanden...

    durch :

    VB.NET-Quellcode

    1. Dim d As blinkerblink = AddressOf newblink ' <-Delegaten adressieren
    2. picBlinker.Invoke(d) '<-die Picbox wird über den Delegaten "angesprochen"
    3. Private Sub newblink() '<- das ist die Prozedur die Mithilfe des Delegaten ausgeführt wird
    4. picBlinker.Visible = Not picBlinker.Visible
    5. 'Hier kann THreadübergreifend mit hilfe des Delegaten auf die PB zugegriffen werden
    6. End Sub
    7. Private Sub blingBling()
    8. Dim d As blinkerblink = AddressOf newblink
    9. If KeepRunning = True Then 'VÖLLIG ÜBERFLÜSSIG
    10. Do While KeepRunning '<- HIER STEHT EINE BEDINGUNG
    11. 'einfach ausgedrückt steht da
    12. 'TU SOLANGE KeepRunning WAHR ist folgendes:
    13. Threading.Thread.Sleep(600)
    14. If picBlinker.InvokeRequired Then : picBlinker.Invoke(d)
    15. Else : picBlinker.Visible = Not picBlinker.Visible
    16. End If
    17. Loop
    18. 'Ist Keeprunning NICHT wahr, dann folgt der Code nach LOOP
    19. Else 'schwachsinn
    20. ' picBlinker.Visible = False <- Hier benutzt du kein Invoke, geht also nicht
    21. End If 'schwachsinn
    22. 'ALSO Statt dem If überflüssigem If, beendet sich der Thread selber, wenn die WHILE Bedingung nicht erfüllt wird , da nach Loop kein COde folgt
    23. 'Möchtest du sichergehen das die PB invisible ist dann mach eine weitere Abfrage:
    24. If picBlinker.Visible Then picBlinker.invoke(d)
    25. End Sub


    erstmal grundlagen lernen für strukturen des programmierens..
    Das ist meine Signatur und sie wird wunderbar sein!