Form Eingefroren bei IP adressenabfrage Webclient

  • VB.NET
  • .NET (FX) 4.0

Es gibt 39 Antworten in diesem Thema. Der letzte Beitrag () ist von bigbase.

    Dann hier die Kurzfassung Deines Sollcodes:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Delegate Sub DelLabelUpdate(NewLabelText As String)
    3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. Dim BackgroundThread = New Threading.Thread(AddressOf GetIP)
    5. BackgroundThread.IsBackground = True
    6. BackgroundThread.Start()
    7. End Sub
    8. Private Sub GetIP()
    9. Dim str = ""
    10. Dim LabelUpdateDelegate As New DelLabelUpdate(AddressOf UpdateLabel)
    11. Invoke(LabelUpdateDelegate, str)
    12. End Sub
    13. Private Sub UpdateLabel(NewLabelText As String)
    14. Label1.Text = NewLabelText
    15. End Sub
    16. End Class


    Leider kann ein Thread keinen Wert zurückgeben, also kann GetIP nichts zurückliefern, wenn sie in einem Nebenthread läuft. Sie muss also selber die gewünschte Ausgabe an Label1 vornehmen.
    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.

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

    VaporiZed schrieb:

    Dann hier die Kurzfassung Deines Sollcodes:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Delegate Sub DelLabelUpdate(NewLabelText As String)
    3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. Dim BackgroundThread = New Threading.Thread(AddressOf GetIP)
    5. BackgroundThread.IsBackground = True
    6. BackgroundThread.Start()
    7. End Sub
    8. Private Sub GetIP()
    9. Dim str = ""
    10. Dim LabelUpdateDelegate As New DelLabelUpdate(AddressOf UpdateLabel)
    11. Invoke(LabelUpdateDelegate, str)
    12. End Sub
    13. Private Sub UpdateLabel(NewLabelText As String)
    14. Label1.Text = NewLabelText
    15. End Sub
    16. End Class


    Leider kann ein Thread keinen Wert zurückgeben, also kann GetIP nichts zurückliefern, wenn sie in einem Nebenthread läuft. Sie muss also selber die gewünschte Ausgabe an Label1 vornehmen.



    Sehr nett danke aber leider bekomme ich das immer noch nicht hin

    Ist auch vorerst egal habe mich damit abgefunden das ich es nicht schaffe

    Das script bekomme ich schon rein aber das mit den rückgabe werten bin ich überfprdert

    mrMo schrieb:

    Schreib im form load Async rein
    -> Private Async Sub (...)

    Dann rufst du im FormLoad deine Methode so auf:

    Dim S = System.Threading.Tasks.Task.Run(Function() GetIP())
    Await S
    Label3.Text = S





    Habe nun auf Visualstuido 2015 Gewechselt habe dann versucht dein Code um zu setzen

    VB.NET-Quellcode

    1. Dim IPlesen = System.Threading.Tasks.Task.Run(Function() GetIP())
    2. Await IPlesen
    3. Label3.Text = IPlesen



    Das endet aber in einem haufen an fehlern

    Quellcode

    1. Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    2. Fehler BC30456 "Run" ist kein Member von "Task". WindowsApplication1 C:\Users\User\Documents\Visual Studio 2010\Projects\WindowsApplication1\WindowsApplication1\Form1.vb 303 Aktiv
    3. Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    4. Fehler BC36930 "Await" erfordert, dass der Typ "?" eine geeignete GetAwaiter-Methode aufweist. WindowsApplication1 C:\Users\User\Documents\Visual Studio 2010\Projects\WindowsApplication1\WindowsApplication1\Form1.vb 304 Aktiv



    Ich kapiere grad selbst noch nicht ganz wie aber ich habe s mit der threading lösung hinbekommen



    Leider hängt es Teilweise immer noch

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „bigbase“ ()

    Schreib den Code mal testweise in ein neues Projekt. Ggf. machen alte Restdaten aus VB2010 das ganze unbrauchbar. Oder Du machst das über Menu [Projekt] -> [DeinProjektName] neu erstellen.

    Zum anderen würde Dein Code richtig lauten:

    VB.NET-Quellcode

    1. Dim IPlesen = Await Threading.Tasks.Task.Run(Function() GetIP())
    2. Label3.Text = IPlesen

    da Await Threading.Tasks.Task.Run(Function() GetIP()) den Rückgabewert Deiner GetIP-Funktion liefert. Hingegen wird bei Dim IPlesen = Threading.Tasks.Task.Run(Function() GetIP()) das IPLesen zu einem Task(Of String), also einer Aufgabe, die zu erledigen ist. Alternativ wäre es natürlich auch möglich zu schreiben:

    VB.NET-Quellcode

    1. Dim IPlesen = Threading.Tasks.Task.Run(Function() GetIP())
    2. Label3.Text = Await IPlesen


    Und Du musst die Funktion, welche die Await-Codes enthält, mit Async versehen, falls noch nicht geschehen, also z.B. Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    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.

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

    theoretisch könntest du die IPGet Funktion auch noch etwas Simpler gestalten,
    z.B.

    VB.NET-Quellcode

    1. Dim str2 As String
    2. str2 = System.Text.RegularExpressions.Regex.Replace((New WebClient()).DownloadString("http://checkip.dyndns.org"), "[^0-9\.]", "")
    3. Return str2


    Greets
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Ich habe das ganze jetzt erweitert und leider noch mehr probleme.... heul


    Also
    IP Adressen abfrage funktioniert ohne Form eingefroren
    Darunter der Reconect.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class frmErmitteln
    2. Public Shared Async Function GetIP(Optional ByVal fritzBox As Boolean = False) As Task(Of String)
    3. Dim str As String
    4. If (Not fritzBox) Then
    5. Dim str1 As String = "0.0.0.0"
    6. Try
    7. Dim str2 As String = ""
    8. str2 = (New WebClient()).DownloadString("http://checkip.dyndns.org")
    9. Dim strArrays As String() = str2.Split(New String() {":", "<"}, StringSplitOptions.RemoveEmptyEntries)
    10. str1 = strArrays(6).Trim()
    11. Catch exception As System.Exception
    12. str = str1
    13. Return str
    14. End Try
    15. str = str1
    16. Else
    17. Dim httpWebRequest As System.Net.HttpWebRequest = DirectCast(WebRequest.Create(" http://fritz.box:49000/igdupnp/control/WANIPConn1"), System.Net.HttpWebRequest)
    18. Dim length As System.Net.HttpWebRequest = httpWebRequest
    19. length.Method = "POST"
    20. length.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"
    21. length.Headers.Add("SOAPACTION", "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress")
    22. length.ContentType = "text/xml; charset=UTF-8"
    23. length.ContentLength = CLng(297)
    24. length.Timeout = 60000
    25. length.AllowAutoRedirect = True
    26. Dim str3 As String = String.Concat(New String() {"<?xml version=""1.0"" encoding=""utf-8""?>", Environment.NewLine, "<s:Envelope s:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"" xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">", Environment.NewLine, " <s:Body>", Environment.NewLine, " <u:GetExternalIPAddress xmlns:u=""urn:schemas-upnp-org:service:WANIPConnection:1"" />", Environment.NewLine, " </s:Body>", Environment.NewLine, "</s:Envelope>"})
    27. If (str3.Length <= 0) Then
    28. str = "0.0.0.0"
    29. Else
    30. length.ContentLength = CLng(CInt(Encoding.UTF8.GetBytes(str3).Length))
    31. Dim requestStream As Stream = httpWebRequest.GetRequestStream()
    32. requestStream.Write(Encoding.UTF8.GetBytes(str3), 0, CInt(Encoding.UTF8.GetBytes(str3).Length))
    33. requestStream.Close()
    34. Dim response As HttpWebResponse = DirectCast(length.GetResponse(), HttpWebResponse)
    35. str = Regex.Split(Regex.Split((New StreamReader(response.GetResponseStream())).ReadToEnd(), "<NewExternalIPAddress>")(1), "</NewExternalIPAddress>")(0)
    36. End If
    37. End If
    38. Return str
    39. End Function
    40. Public Shared Async Sub ChangeIpFritzbox()
    41. Dim p As String = Await GetIP(True)
    42. Dim str As String = String.Concat(New String() {String.Concat(New String() {"POST /igdupnp/control/WANIPConn1 HTTP/1.1", Environment.NewLine, "HOST: fritz.box:49000", Environment.NewLine, "SOAPACTION: ""urn:schemas-upnp-org:service:WANIPConnection:1#ForceTermination""", Environment.NewLine, "CONTENT-TYPE: text/xml ; charset=""utf-8""", Environment.NewLine, "Content-Length: 293", Environment.NewLine}), Environment.NewLine, "<?xml version=""1.0"" encoding=""utf-8""?>", Environment.NewLine, "<s:Envelope s:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"" xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">", Environment.NewLine, " <s:Body>", Environment.NewLine, " <u:ForceTermination xmlns:u=""urn:schemas-upnp-org:service:WANIPConnection:1"" />", Environment.NewLine, " </s:Body>", Environment.NewLine, "</s:Envelope>"})
    43. Dim tcpClient As System.Net.Sockets.TcpClient = New System.Net.Sockets.TcpClient()
    44. tcpClient.Connect("fritz.box", 49000)
    45. Dim stream As NetworkStream = tcpClient.GetStream()
    46. Dim bytes(str.Length + 1 - 1) As Byte
    47. bytes = Encoding.ASCII.GetBytes(str)
    48. stream.Write(bytes, 0, CInt(bytes.Length))
    49. ReDim bytes(1024)
    50. Dim empty As String = String.Empty
    51. Dim num As Integer = stream.Read(bytes, 0, CInt(bytes.Length))
    52. empty = Encoding.ASCII.GetString(bytes, 0, num)
    53. stream.Close()
    54. tcpClient.Close()
    55. Thread.Sleep(1250)
    56. Dim num1 As Integer = 0
    57. Dim p1 As String = "0.0.0.0"
    58. Thread.Sleep(1000)
    59. While p1 = "0.0.0.0"
    60. Thread.Sleep(500)
    61. If (num1 > 30) Then
    62. p1 = "Failed"
    63. End If
    64. If (num1 > 8) Then
    65. Thread.Sleep(1500)
    66. End If
    67. p1 = Await GetIP(True)
    68. num1 = num1 + 1
    69. End While
    70. num1 = 0
    71. While p = p1
    72. Thread.Sleep(1000)
    73. p1 = Await GetIP(True)
    74. num1 = num1 + 1
    75. If (num1 > 450) Then
    76. MessageBox.Show(String.Concat("IP-Adresse scheint sich nicht geändert zu haben", num1))
    77. Exit While
    78. End If
    79. End While
    80. Dim IPlesen = Threading.Tasks.Task.Run(Function() frmErmitteln.GetIP())
    81. Form1.Label3.Text = Await IPlesen
    82. End Sub
    83. End Class


    VB.NET-Quellcode

    1. Dim IPlesen = Threading.Tasks.Task.Run(Function() frmErmitteln.GetIP())
    2. Label3.Text = Await IPlesen


    Aber die form friert ein bis der reconect durchgeführt wurde wo hat sich der fehler eingeschlichen.


    aufruf der funktion

    VB.NET-Quellcode

    1. Private Async Sub Button23_Click(sender As Object, e As EventArgs) Handles Button23.Click
    2. frmErmitteln.ChangeIpFritzbox()
    3. End Sub


    Ich glaube so sind alle Codes da um das auch nach zu stellen

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

    bigbase schrieb:

    drück dich doch mal ricitig aus
    Das tu ich die ganze Zeit - ich wunder mich, wie schwer verständlich das für dich ist.

    Aber ich kopiere die gemeinten Snippets jetzt mal zusammen, weil du sie trotz meiner eindeutigen Angaben ja nicht zu finden scheinst:
    Also post#24, Snippet#1:

    VaporiZed schrieb:

    VB.NET-Quellcode

    1. Dim IPlesen = Await Threading.Tasks.Task.Run(Function() GetIP())
    2. Label3.Text = IPlesen


    post#27, Snippet#2

    bigbase schrieb:

    VB.NET-Quellcode

    1. Dim IPlesen = Threading.Tasks.Task.Run(Function() frmErmitteln.GetIP())
    2. Label3.Text = Await IPlesen
    Ich hoffe, du siehst den Unterschied jetzt auch - er betrifft die Position des Await-Schlüsselworts in den Snippets.

    Wie in post#28 gesagt: ich weiß nicht, ob der Unterschied sich auswirkt - das war ja meine Frage an dich.



    Dabei fällt mir noch ein weiterer Unterschied auf, der höchstwahrscheinlich noch viel entscheidender ist: Bei Vaporized steht Function() GetIP(), und bei dir: Function() frmErmitteln.GetIP().
    Letzteres erzeugt in Threading-Szenarien eine neue, unsichtbare Form-Instanz, also es wird die Methode .GetIP eines ganz anderen Forms addressiert, als welches du anguckst.
    Solch führt eiglich immer zu äusserst überraschendem Fehlverhalten.


    (Edit: Letzteres muss ich zurücknehmen, nachdem ich wahrgenommen habe, dass dein GetIP() Shared ist.)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ich denke mal er meint diese Zeile:

    VB.NET-Quellcode

    1. Dim IPlesen = Threading.Tasks.Task.Run(Function() frmErmitteln.GetIP())
    2. Label3.Text = Await IPlesen


    die sieht in post 24 noch anders aus

    Greets
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Ah - ok. Dann hättest du den Code vlt besser garnet gepostet - v.a. net so exponiert.
    Ich gehe bei gepostetem Code immer davon aus, dass er etwas mit der Frage zu tun hat.



    Gut - nachdem das geklärt ist, gugge ich nochmal dein Code und ist nicht verwunderlich, dass dieses das Form einfriert:

    Post#27 schrieb:

    VB.NET-Quellcode

    1. Private Async Sub Button23_Click(sender As Object, e As EventArgs) Handles Button23.Click
    2. frmErmitteln.ChangeIpFritzbox()
    3. End Sub

    Du brauchst ChangeIpFritzbox() nicht mit Async modifizieren, sondern du musst es mit Await aufrufen, eingeschachtelt in Task.Run() - halt ebenso wie du GetIP() aufrufst.


    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „ErfinderDesRades“ ()

    VB.NET-Quellcode

    1. Private Async Sub Button23_Click(sender As Object, e As EventArgs) Handles Button23.Click
    2. Await Task.Run(Addressof frmErmitteln.ChangeIpFritzbox)
    3. End Sub
    Das ist die einfachste Variante.



    Sie führt aber auf den nächsten Fehler, weil du innerhalb von ChangeIP() aufs Form zugreifst (also dort genau den Fehler machst, den ich in post#34 für den GetIP()-Aufruf zurückgenommen habe).

    Lösung: Gestalte ChangeIP() nach dem Muster von GetIP, also es darf nicht mit Zuweisungen an Label3 in ein Form grabschen, sondern soll einfach sein Ergebnis returnen. Nur so gelangt das Ergebnis in den MainThread - anders kann es nicht korrekt verarbeitet werden.

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