Schleife über gesamte Sub

  • VB.NET
  • .NET (FX) 4.0

Es gibt 49 Antworten in diesem Thema. Der letzte Beitrag () ist von markoh2603.

    Schleife über gesamte Sub

    Hallo,

    ich habe folgendes Problem. Ich schreibe gerade ein Programm, welches
    aus appsettings die hostnamen ausliest und diese in einer Groupbox
    ausgibt. Dazu wird gleich der Online-Status der hostnamen mit ausgegeben
    (als Labels innerhalb der Groupbox). Das Problem was ich gerade habe,
    ist folgendes. Der Online-Status ist ja immer nur der Stand vom Start
    des Programmes. Ich würde den Stand aber gern aller 30 sek.
    aktualisieren. Dazu müßten ja nur die "Status-Labels" neu geladen
    werden, aber irgendwie steh ich hier total auf dem Schlauch. Ob das
    ganze über eine Schleife mit Backgroundworker oder über ein
    Timer-Element realiert würde, wäre mir dabei gänzlich egal.

    Hier mal der bisherige Code:

    Quellcode

    1. Private Sub statusbox_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. 'Klassenbibliothek presenter aufrufen
    3. Dim prog As New presenter.presenter
    4. Dim host As String = CStr(My.Settings.Item("presenter"))
    5. Dim liste As New ArrayList(host.Split(CChar(";")))
    6. Dim ls(liste.Count) As Label
    7. Dim ls2(liste.Count) As Label
    8. Dim result(liste.Count) As Boolean
    9. For i = 0 To liste.Count
    10. ls(i) = New Label
    11. ls2(i) = New Label
    12. ls(i).Name = CStr((liste(i)))
    13. ls(i).ForeColor = Color.Black
    14. ls(i).Text = CStr((liste(i)))
    15. ls(i).Location = New Point(8, 30 * i + 20)
    16. ls(i).Size = CType(New System.Drawing.Point(100, 20), Drawing.Size)
    17. Try
    18. result(i) = CBool(prog.ping(CStr(liste(i))))
    19. If result(i) = True Then
    20. ls2(i).ForeColor = Color.Green
    21. ls2(i).Text = "Online"
    22. End If
    23. Catch ex As Exception
    24. ls2(i).ForeColor = Color.Red
    25. ls2(i).Text = "Offline"
    26. End Try
    27. ls2(i).Name = CStr((liste(i)))
    28. ls2(i).Location = New Point(110, 30 * i + 20)
    29. ls2(i).Size = CType(New System.Drawing.Point(60, 20), Drawing.Size)
    30. statusbox.Controls.Add(CType(ls(i), Control))
    31. statusbox.Controls.Add(CType(ls2(i), Control))
    32. Next
    33. End Sub



    Ich bedanke mich schonmal.

    MarkOH

    P.S. Verwende VB 2010

    markoh2603 schrieb:

    Jo das habe ich schon probiert
    Mit welchem Code?
    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!

    markoh2603 schrieb:

    die Labels im Timer zu erzeugen.
    Die solltest Du im Designer anlegen.
    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!
    Ich kann die Labels im Designer nicht erstellen, weil sie dynamisch erzeugt werden, anhand der hostnamen welche in der appconfig-Datei übergeben werden. Stehen dort 3 hostnamen drin müssen 3 Labels erzeugt werden, steht nur 1 hostname drin, nur 1 Label und dazu immer das Label, ob der Host erreichbar ist oder nicht. Das wird über eine Funktion in einer dll gemacht, wo My.Computer.Network.Ping aufgerufen wird. Anhand des Ergebnisses wird das Label rot oder grün "gefärbt".

    Ich habe noch nicht viel Erfahrung mit VB.Net, möchte hier auch nicht, dass mir jemand den fertigen Code zusammenhackt. Ich hätte nur gern eine Erklärung wie ich oben geposteten Code so umschreiben kann, dass über ein Timer-Element aller 30 Sekunden der Status der Labels neu erzeugt wird.
    Das ist schon richtig, nur müßte ich jedesmal, wenn sich ein host ändert, im Programm die entsprechende Änderung programmieren. Da sich hier immermal Änderungen ergeben können, ein Host kommt hinzu oder einer fällt weg, wollte ich das ganze halt dynamisch halten indem ich nur in der test.exe.config den host hinzufüge oder entferne, aber keine Änderungen direkt im Programm machen muss oder habe ich gerade einen Knoten im Hirn und versteh nicht was du sagen möchtest.
    Also es wird nicht so sein, dass das Programm läuft und zeitgleich die Änderung in der test.exe.config gemacht wird. Denke das kann ich komplett unbeachtet lassen. Wird eine Änderung in der test.exe.config gemacht wurde vorher das Programm geschlossen.
    Es geht darum, dass angezeigt werden soll, ob der Host noch erreichbar ist, sprich My.Computer.Network.Ping True oder False ausspuckt und anhand dieses Ergebnisses, dass Label grün oder rot färbt. Zum Programmstart werden die Hosts ja schon gepingt, sodass ein entsprechendes Ergebnis vorliegt. Aber mit Laufzeit des Programms kann sich ja der Zustand der Hosts ändern, aus diesem Grund, würde ich gern die Labels aller 30 sek. neu erzeugen.
    Ich glaube ich steh heute wirklich total aufm Schlauch oder kann mich nicht richtig ausdrücken.

    OK nochmal von vorn. Ich erzeuge soviele ls labels wie es hostnamen in meiner appconfig gibt (Der Labeltext = hostname) Der Labelname wäre ls(0), ls(1) etc.. Daneben erstelle ich genausoviele ls2 labels wie es ls labels gibt die den Text online oder offline haben und die Farbe grün oder rot. Das hängt davon ab, ob My.Computer.Network.Ping True oder False ausgibt. Labelname ls2(0) ls2(1) etc.

    Das was jetzt aller 30 sek neu erzeugt werden soll, sind die ls2 labels, da sich deren Status ändern kann, die ls-labels werden sich für die Laufzeit des Programms nicht ändern.
    Die Labelnamen müßten doch dann wieder ls2(0) ls2(1) etc sein, sodass doch nicht immer weitere Labels erzeugt werden, sondern sich nur der Labeltext und Farbe ändert oder sehe ich das falsch.
    Ahoi,

    also wenn ich das richtig verstanden habe. Du erzeugst deine Labels dynamisch aus deiner Config-Datei, welche nicht in der Laufzeit geändert wird. Willst alle 30 Sekunden einen Ping ausführen und je nach Resultat die Farbe ändern.
    Das sieht für mich nach sauber abgrenzbaren Paketen aus.
    Die Labels kannst du beim Start dynamisch oder statisch erzeugen wie du lustig bist.
    Daraufhin startest du den Timer... ich glaube das war so was mit ticker (.net ist schon etwas her).
    Im Ticker/Timer-Event, wie auch immer das hieß, führst du die pings aus und veränderst nur noch die Farb-Attribute der Labels, da brauchst du nix neu erstellen.
    Wenn ich richtig zähle, wären das 1-Load-Event zum Starten mit Herstellung der Labels. Eine function ping() und eine function farbe_ändern() und ein timer-event.
    mach summa sumarum 4 functions die wunderbar als Pakete abgearbeitet werden können :D

    EDIT: irgendjemand hatte es mal gesagt und ich stimme zu ... die Benachrichtigung, dass während man geschrieben hat weitere Antworten erstellt wurden fehlt -.-
    Grüße Manu

    Was Gott dem Menschen erspart hat, kann der Computer.
    Billy ©, (*1932), Schweizer Aphoristiker
    Quelle: www.Aphorismen.de

    markoh2603 schrieb:

    OK nochmal von vorn.
    Poste bitte eine Problembeschreibung ohne eine Lösung vorwegzunehmen.
    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!
    Hallo,

    da ich gestern keine Zeit hatte, habe ich mich heute mal an die ganze Sache gesetzt. Ich glaube, dass ich soweit verstanden habe, was Manu erklärt hat.
    Ich poste mal meinen bisherigen Zwischenstand und gleich mein aktuelles Problem:

    Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Imports System.Runtime.InteropServices
    4. Imports Microsoft.Win32
    5. Imports System.IO
    6. Imports System.Diagnostics
    7. Imports System.Threading
    8. Imports System.Configuration
    9. Imports System.Collections.Specialized
    10. Public Class planpresenter
    11. Private Sub statusbox_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    12. Timer1.Enabled = True
    13. Timer1.Interval = 10000
    14. End Sub

    Ich habe den Timer mal auf 10 Sek. gestellt, damit ich schneller Ergebnisse bekomme.

    Quellcode

    1. Function ping(ByVal host As String) As String
    2. Dim Result As Boolean
    3. Try
    4. Result = (My.Computer.Network.Ping(host))
    5. Return CStr(Result)
    6. Catch ex As Exception
    7. Result = CBool(False)
    8. Return CStr(Result)
    9. End Try
    10. End Function
    11. Function farbe_ändern(ByVal result As String) As System.Drawing.Color
    12. Dim Farbe As System.Drawing.Color
    13. If result = "True" Then
    14. Farbe = (Color.Green)
    15. Else
    16. Farbe = (Color.Red)
    17. End If
    18. Return (Farbe)
    19. End Function
    20. Function read_hosts() As ArrayList
    21. Dim host As String = CStr(My.Settings.Item("presenter"))
    22. Dim liste As New ArrayList(host.Split(CChar(";")))
    23. Return liste
    24. End Function


    Ich habe jetzt die Funktionen ping(), farbe_ändern() und read_hosts(). Die read_hosts() habe ich noch hinzugefügt, da ich einem weiteren Teil des Programms die Hostnamen erneut benötigen werde.

    Quellcode

    1. Private Sub Timer1_Tick_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2. Dim host_arraylist = read_hosts()
    3. Dim ping_result(host_arraylist.Count) As Boolean
    4. Dim host_label(host_arraylist.Count) As Label
    5. Dim status_label(host_arraylist.Count) As Label
    6. ''Dim farbe(host_array.Count) As System.Drawing.Color
    7. 'MessageBox.Show(CStr(host_arraylist.Count))
    8. For i = 0 To host_arraylist.Count
    9. ping_result(i) = CBool(ping(CStr(host_arraylist(i))))
    10. MessageBox.Show(CStr(host_arraylist(i)) & " " & ping_result(i))
    11. ' 'host_label(i).Name = CStr(host_arraylist(i))
    12. ' 'host_label(i).Text = CStr(host_arraylist(i))
    13. ' 'status_label(i).ForeColor = farbe_ändern(ping_result(i))
    14. Next
    15. End Sub

    Und zu guter letzt der Timer der zuerst die hosts aus der Funktion read_hosts() holt und dann die Funktion ping() aufruft.
    Jetzt aber mein aktuelles Problem. Hier bekomme ich ein:

    Quellcode

    1. System.ArgumentOutOfRangeException wurde nicht behandelt.
    2. HResult=-2146233086
    3. Message=Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein.
    4. Parametername: index
    5. ParamName=index
    6. Source=mscorlib
    7. StackTrace:
    8. bei System.Collections.ArrayList.get_Item(Int32 index)
    9. bei planpresenter.planpresenter.Timer1_Tick_1(Object sender, EventArgs e) in C:\Users\marco.monden\Documents\Visual Studio 2010\Projects\planpresenter\planpresenter\planpresenter.vb:Zeile 132.
    10. bei System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
    11. bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    12. bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    13. bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    14. bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    15. bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    16. bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    17. bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    18. bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    19. bei planpresenter.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:Zeile 81.
    20. bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    21. bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    22. bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    23. bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    24. bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    25. bei System.Threading.ThreadHelper.ThreadStart()
    26. InnerException:


    Ich finde leider den Grund des Fehlers nicht :(

    Viele Grüße

    Mark

    markoh2603 schrieb:

    VB.NET-Quellcode

    1. Function ping(ByVal host As String) As String

    markoh2603 schrieb:

    VB.NET-Quellcode

    1. Function farbe_ändern(ByVal result As String) As System.Drawing.Color
    Mach da mal dies draus:

    VB.NET-Quellcode

    1. Function ping(ByVal host As String) As Boolean
    2. Function farbe_ändern(ByVal result As Boolean) As System.Drawing.Color
    Und falls Du es noch nicht hast: Option Strict On.
    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!