Webbrowser multithreaded verwenden ?

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

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Webbrowser multithreaded verwenden ?

    Hi @ All,

    ich hab mal wieder eine etwas "unschöne" Frage, und zwar, arbeite ich an einem Programm welches, sich mit der Webseite unserer Arbeit verbindet, sich dort einloggt, einen neuen Link aufruft wartet bis der geladen ist (mit picoflops Browser.NavigateAsync)
    dann etwas aus dem Quelltext filtert, an sich funktioniert dies einwandfrei, allerdings immer ein Link nach dem anderen, jetzt wollte ich mich mal dransetzen und versuchen dies Multithreaded hinzubekommen (hier ist auch der unschöne Teil da ich CrossthreadCalls verwende)

    allerdings bekomme ich es gar nicht erst zum laufen da er meckert :

    Spoiler anzeigen
    Eine Ausnahme vom Typ "System.Threading.ThreadStateException" ist in System.Windows.Forms.dll aufgetreten, doch wurde diese im Benutzercode nicht verarbeitet.

    Zusätzliche Informationen: Das ActiveX-Steuerelement 8856f961-340a-11d0-a96b-00c04fd705a2 kann nicht instanziiert werden, da der aktuelle Thread kein Singlethread-Apartment ist.



    was genau ist denn damit gemeint ??


    Aktueller Code (erstmal rufe ich nur einen Befehl im neuen thread auf da er ja nicht mal einen abarbeiten will...)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Environment
    2. Public Class Main
    3. Dim wb As New WebBrowser
    4. Dim res As String
    5. Dim old As String
    6. Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. CheckForIllegalCrossThreadCalls = False
    8. wb.ScriptErrorsSuppressed = True
    9. Clipboard.Clear()
    10. old = Clipboard.GetText
    11. timAutoInsert.Enabled = True
    12. End Sub
    13. Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    14. 'ClearIDList()
    15. Dim t As Thread
    16. t = New Thread(Sub() GetState(rtbIDs.Lines(0)))
    17. t.Start()
    18. rtbErgebnisse.Text = res
    19. End Sub
    20. Private Sub rtbIDs_TextChanged(sender As Object, e As EventArgs) Handles rtbIDs.TextChanged
    21. lblIDCount.Text = "Zu prüfende IDs: " & rtbIDs.Lines.Count
    22. End Sub
    23. Private Sub ClearIDList()
    24. '// Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    25. If rtbIDs.Text.Contains("https://payangocard.de/admin/orders/") Then
    26. rtbIDs.Text = rtbIDs.Text.Replace("https://payangocard.de/admin/orders/", "")
    27. End If
    28. rtbIDs.Refresh()
    29. rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Length > 0 Select s).ToArray
    30. ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1)
    31. rtbIDs.Refresh()
    32. If rtbIDs.Text.Contains(" ") Then
    33. rtbIDs.Text = rtbIDs.Text.Replace(" ", "")
    34. End If
    35. rtbIDs.Refresh()
    36. rtbIDs.SelectionStart = 0
    37. rtbIDs.ScrollToCaret()
    38. rtbIDs.Refresh()
    39. '// Ende Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    40. End Sub
    41. Private Async Sub GetState(ByVal ID As String)
    42. '// eigentliche Funktion
    43. Dim wsb As New WebBrowser
    44. wsb.ScriptErrorsSuppressed = True
    45. Await wb.NavigateTaskAsync("https://payangocard.de/session/new")
    46. wsb.Document.GetElementById("login").InnerText = "*"
    47. wsb.Document.GetElementById("password").InnerText = "*"
    48. wsb.Document.Forms(0).InvokeMember("submit")
    49. Do Until wsb.DocumentText.Contains("Sie wurden erfolgreich eingeloggt") _
    50. OrElse wsb.DocumentText.Contains("Bitte überprüfen Sie Ihr Passwort.") _
    51. OrElse wsb.DocumentText.Contains("Bitte überprüfen Sie Ihren Benutzernamen bzw. Ihre E-Mail-Adresse.") _
    52. OrElse wsb.DocumentText.Contains("Sie haben die maximale Anzahl der möglichen Loginversuche überschritten und sind für eine Stunde gesperrt.")
    53. Loop
    54. Await wsb.NavigateTaskAsync("https://payangocard.de/admin/orders/" & ID)
    55. Dim a As Match = Regex.Match(wsb.DocumentText, "Status: ([^\(]*)", RegexOptions.IgnoreCase)
    56. If (a.Success) Then
    57. Dim key As String = a.Groups(1).Value
    58. res = res & NewLine & key
    59. End If
    60. Close()
    61. '// Ende eigentliche Funktion
    62. End Sub
    63. Private Sub timAutoInsert_Tick(sender As Object, e As EventArgs) Handles timAutoInsert.Tick
    64. If Clipboard.GetText <> old Then
    65. rtbIDs.Text = rtbIDs.Text & Clipboard.GetText & NewLine
    66. rtbIDs.SelectionStart = rtbIDs.Text.Length
    67. rtbIDs.ScrollToCaret()
    68. Clipboard.Clear()
    69. old = Clipboard.GetText
    70. End If
    71. End Sub
    72. Private Sub chbCopy_CheckedChanged(sender As Object, e As EventArgs) Handles chbCopy.CheckedChanged
    73. If timAutoInsert.Enabled = True Then
    74. timAutoInsert.Enabled = False
    75. ElseIf timAutoInsert.Enabled = False Then
    76. Clipboard.Clear()
    77. old = Clipboard.GetText
    78. timAutoInsert.Enabled = True
    79. End If
    80. End Sub
    81. End Class



    wieso tritt dieser fehler auf und wie könnte ich diesen umgehen ?

    Greets

    p.S. es muss leider ein Webbrowser verwendet werden da die Webseite mit Zertifikaten arbeitet und ich es damals in Monatelangen Tests nur mit einem Browser entsprechend aufrufen konnte...
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Mal versucht den/das Thread Apartment auf STA (Singlethread-Apartment) zu stellen?

    Dim t As Thread
    t = New Thread(Sub() GetState(rtbIDs.Lines(0)))
    t.SetApartmentState(ApartmentState.STA)
    t.Start()

    Ich würde dir die Async Variante empfehlen. Einen Thread zu starten kostet Zeit, die man nur investieren sollte wenn man enorm lange/rechenintensive Methoden laufen hat. Bei dem was du machst, reicht die Async Variante sicher aus.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo he danke dir so schmiert er schon mal nicht ab ^^

    ich wüsste ehrlich nicht wo mir Async hier helfen könnte, soweit ich verstanden hatte ist async zu nutzen wenn man auf etwas warten will, die threads sollen ja alles zeitgleich machen, und nicht abwarten oder so, sonst könnte ich ja theoretisch dabei bleiben einem Link nach dem anderen abzuarbeiten
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

    asusdk schrieb:

    soweit ich verstanden hatte ist async zu nutzen wenn man auf etwas warten will, die threads sollen ja alles zeitgleich machen, und nicht abwarten oder so, sonst könnte ich ja theoretisch dabei bleiben einem Link nach dem anderen abzuarbeiten


    Du kannst x beliebig viele Tasks starten und am ende auf die ergebnisse aller Tasks "warten"

    Oder aber du startest im Task eine Methode, die alle deine Links abarbeitet.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @asusdk: Das "Await" beim Async/Await-Konstrukt heißt zwar "erwarten", aber wohl anders, als Du vermutest.
    Ein Programm folgt standardmäßig einem Weg und arbeitet diesen ab.

    VB.NET-Quellcode

    1. Private Sub Start()
    2. A()
    3. B()
    4. C()
    5. End Sub
    6. Private Async Sub A()
    7. Await Threading.Tasks.Task.Delay(3000)
    8. My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
    9. End Sub
    10. Private Async Sub B()
    11. Await Threading.Tasks.Task.Delay(5000)
    12. My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Question)
    13. End Sub
    14. Private Async Sub C()
    15. Await Threading.Tasks.Task.Delay(7000)
    16. My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Hand)
    17. End Sub

    Hier wird in A, B, C darauf gewartet, dass ne bestimmte Sache erledigt ist (in dem Fall bis x Sekunden vergangen sind), bevor der jeweilige Ton abgespielt wird. Aber es wird im 2-Sekunden-Takt was gespielt. Nicht nach 3 Sekunden, danach erst nach 5s und dann erst nach 7s, also nach insgesamt 15s, sondern tatsächlich ist der letzte Sound nach 7s abgespielt.

    Man kann sich das so vorstellen: Der Computer ist ein Baustellenfahrzeug voller motivierter Arbeiter. Sie sind auf einer Straße unterwegs und reparieren Schlaglöcher. In einem normalen Programm bleibt das Fahrzeug stehen, ein Arbeiter steigt aus, behebt das Problem (eine Programmaufgabe/Codezeile wird abgearbeitet), weiter geht's.
    Beim Async/Await-Konstrukt (und anderen Parallelitätskonstrukten) geschieht was anderes. Bei solch einer Baustelle/Zeile steigt ein Arbeiter A aus, während die anderen zur nächsten Baustelle weiterfahren und sich um diese kümmern. Sobald A mit seiner Aufgabe fertig ist, kümmert er sich noch um die Stellen, die dahinter noch zu erledigen sind (die Zeilen nach Await).
    Auf diese Weise kann man für viele Baustellen gleichzeitig jeweils einen Arbeiter abstellen, der sich um eine Await-Baustelle kümmert, während das Baustellenfahrzeug weiter die Straße/das Programm abfährt.
    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 1 mal editiert, zuletzt von „VaporiZed“ ()

    Private Sub Start()
    A()
    B()
    C()
    End Sub

    Private Async Sub A()
    Await Threading.Tasks.Task.Delay(3000)
    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
    End Sub

    Private Async Sub B()
    Await Threading.Tasks.Task.Delay(5000)
    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Question)
    End Sub

    Private Async Sub C()
    Await Threading.Tasks.Task.Delay(7000)
    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Hand)
    End Sub




    ?? dann müsste ich für jede zu verarbeitende Zeile enen eigenen Sub anlegen ? oder wie jetzt ?
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Nein, natürlich nicht. Das war ja nur'n Beispiel. Nix hindert Dich daran, immer dieselbe Sub aufzurufen, was Du aber durch einfaches probieren selbst rausgefunden hättest:

    VB.NET-Quellcode

    1. Private Sub Start()
    2. WaitAndThenPlaySound(New TimeSpan(0, 0, 3), Media.SystemSounds.Beep)
    3. WaitAndThenPlaySound(New TimeSpan(0, 0, 7), Media.SystemSounds.Question)
    4. WaitAndThenPlaySound(New TimeSpan(0, 0, 11), Media.SystemSounds.Hand)
    5. End Sub
    6. Private Async Sub WaitAndThenPlaySound(dur As TimeSpan, sound As Media.SystemSound)
    7. Await Threading.Tasks.Task.Delay(dur)
    8. My.Computer.Audio.PlaySystemSound(sound)
    9. End Sub

    Du kannst mit ner Await-Prozedur so ziemlich das gleiche wie mit ner normalen Prozedur machen. Parameter übergeben, überladen, ...
    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.
    @VaporiZed
    ok, habs mal eben ausprobiert, ist an sich sicherlich nicht verkehrt,
    aber wenn ich das alles über einen Webbrowser laufen lasse, ist am Ende
    jedes Ergebnis das gleiche (und damit falsch)
    erstelle ich für jede
    ID einen eigenen Browser braucht er für die Aufgaben länger als wenn ich
    sie nacheinander abarbeite, schade eigentlich

    Edit:

    Evtl. (oder wahrscheinlich) übersehe ich ja etwas

    Original Variante:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Environment
    2. Public Class Main
    3. Dim wb As New WebBrowser
    4. Dim SW As New Stopwatch
    5. Dim old As String
    6. Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. wb.ScriptErrorsSuppressed = True
    8. Clipboard.Clear()
    9. old = Clipboard.GetText
    10. timAutoInsert.Enabled = True
    11. End Sub
    12. Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    13. ClearIDList()
    14. GetState()
    15. End Sub
    16. Private Sub rtbIDs_TextChanged(sender As Object, e As EventArgs) Handles rtbIDs.TextChanged
    17. lblIDCount.Text = "Zu prüfende IDs: " & rtbIDs.Lines.Count
    18. End Sub
    19. Private Sub ClearIDList()
    20. '// Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    21. If rtbIDs.Text.Contains("https://payangocard.de/admin/orders/") Then
    22. rtbIDs.Text = rtbIDs.Text.Replace("https://payangocard.de/admin/orders/", "")
    23. End If
    24. rtbIDs.Refresh()
    25. rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Length > 0 Select s).ToArray
    26. ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1)
    27. rtbIDs.Refresh()
    28. If rtbIDs.Text.Contains(" ") Then
    29. rtbIDs.Text = rtbIDs.Text.Replace(" ", "")
    30. End If
    31. rtbIDs.Refresh()
    32. rtbIDs.SelectionStart = 0
    33. rtbIDs.ScrollToCaret()
    34. rtbIDs.Refresh()
    35. '// Ende Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    36. End Sub
    37. Private Async Sub GetState()
    38. '// eigentliche Funktion
    39. SW.Start()
    40. Await wb.NavigateTaskAsync("https://payangocard.de/session/new")
    41. wb.Document.GetElementById("login").InnerText = "*"
    42. wb.Document.GetElementById("password").InnerText = "*"
    43. wb.Document.Forms(0).InvokeMember("submit")
    44. Do Until wb.DocumentText.Contains("Sie wurden erfolgreich eingeloggt") _
    45. OrElse wb.DocumentText.Contains("Bitte überprüfen Sie Ihr Passwort.") _
    46. OrElse wb.DocumentText.Contains("Bitte überprüfen Sie Ihren Benutzernamen bzw. Ihre E-Mail-Adresse.") _
    47. OrElse wb.DocumentText.Contains("Sie haben die maximale
    48. Anzahl der möglichen Loginversuche überschritten und sind für eine
    49. Stunde gesperrt.")
    50. Application.DoEvents()
    51. Loop
    52. Select Case True
    53. Case wb.DocumentText.Contains("Sie wurden erfolgreich eingeloggt")
    54. For I As Integer = 0 To rtbIDs.Lines.Count - 1
    55. lblTime.Text = "ElapsedTime: " &
    56. SW.Elapsed.Minutes & ":" & SW.Elapsed.Seconds & ":" &
    57. SW.Elapsed.Milliseconds
    58. lblInWork.Text = "Verarbeite gerade ID Nr.: " & (I + 1).ToString
    59. Await wb.NavigateTaskAsync("https://payangocard.de/admin/orders/" & rtbIDs.Lines(I))
    60. Dim a As Match = Regex.Match(wb.DocumentText, "Status: ([^\(]*)", RegexOptions.IgnoreCase)
    61. If (a.Success) Then
    62. Dim key As String = a.Groups(1).Value
    63. rtbErgebnisse.Text = rtbErgebnisse.Text & NewLine & rtbIDs.Lines(I) & " - " & key
    64. rtbErgebnisse.Text = rtbErgebnisse.Text.Trim
    65. rtbErgebnisse.SelectionStart = rtbErgebnisse.Text.Length
    66. rtbErgebnisse.ScrollToCaret()
    67. End If
    68. Next
    69. lblInWork.Text = "Completed"
    70. Media.SystemSounds.Asterisk.Play()
    71. SW.Reset()
    72. Case Else
    73. Close()
    74. End Select
    75. Await wb.NavigateTaskAsync("https://payangocard.de/logout")
    76. '// Ende eigentliche Funktion
    77. End Sub
    78. Private Sub timAutoInsert_Tick(sender As Object, e As EventArgs) Handles timAutoInsert.Tick
    79. If Clipboard.GetText <> old Then
    80. rtbIDs.Text = rtbIDs.Text & Clipboard.GetText & NewLine
    81. rtbIDs.SelectionStart = rtbIDs.Text.Length
    82. rtbIDs.ScrollToCaret()
    83. Clipboard.Clear()
    84. old = Clipboard.GetText
    85. End If
    86. End Sub
    87. Private Sub chbCopy_CheckedChanged(sender As Object, e As EventArgs) Handles chbCopy.CheckedChanged
    88. If timAutoInsert.Enabled = True Then
    89. timAutoInsert.Enabled = False
    90. ElseIf timAutoInsert.Enabled = False Then
    91. Clipboard.Clear()
    92. old = Clipboard.GetText
    93. timAutoInsert.Enabled = True
    94. End If
    95. End Sub
    96. End Class


    MultiVersion mit nur einem Browser :

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Environment
    3. Public Class Main
    4. Public wb As New WebBrowser
    5. Public a(5000) As Match
    6. Public Key(5000) As String
    7. Dim SW As New Stopwatch
    8. Dim old As String
    9. Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    10. Clipboard.Clear()
    11. old = Clipboard.GetText
    12. timAutoInsert.Enabled = True
    13. End Sub
    14. Private Async Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    15. ClearIDList()
    16. wb.ScriptErrorsSuppressed = True
    17. Await wb.NavigateTaskAsync("http://payangocard.de/session/new")
    18. Thread.Sleep(200)
    19. Do Until wb.IsBusy = False AndAlso wb.ReadyState = WebBrowserReadyState.Complete ' # Während Browser Lädt
    20. Loop
    21. wb.Document.GetElementById("login").InnerText = "*"
    22. wb.Document.GetElementById("password").InnerText = "*"
    23. wb.Document.Forms(0).InvokeMember("submit")
    24. Do Until wb.DocumentText.Contains("Mein Account")
    25. Loop
    26. For i As Integer = 0 To rtbIDs.Lines.Count - 1
    27. GetState(rtbIDs.Lines(i).ToString, i)
    28. Next
    29. End Sub
    30. Private Sub rtbIDs_TextChanged(sender As Object, e As EventArgs) Handles rtbIDs.TextChanged
    31. lblIDCount.Text = "Zu prüfende IDs: " & rtbIDs.Lines.Count
    32. End Sub
    33. Private Sub ClearIDList()
    34. '// Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    35. If rtbIDs.Text.Contains("https://payangocard.de/admin/orders/") Then
    36. rtbIDs.Text = rtbIDs.Text.Replace("https://payangocard.de/admin/orders/", "")
    37. End If
    38. Thread.Sleep(50)
    39. rtbIDs.Refresh()
    40. rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Length > 0 Select s).ToArray
    41. ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1)
    42. Thread.Sleep(50)
    43. rtbIDs.Refresh()
    44. If rtbIDs.Text.Contains(" ") Then
    45. rtbIDs.Text = rtbIDs.Text.Replace(" ", "")
    46. End If
    47. Thread.Sleep(50)
    48. rtbIDs.Refresh()
    49. rtbIDs.SelectionStart = 0
    50. rtbIDs.ScrollToCaret()
    51. Thread.Sleep(50)
    52. rtbIDs.Refresh()
    53. '// Ende Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    54. End Sub
    55. Private Async Sub GetState(ByVal strID As String, ByVal nrID As Integer)
    56. '// eigentliche Funktion
    57. Await wb.NavigateTaskAsync("https://payangocard.de/admin/orders/" & strID)
    58. a(nrID) = Regex.Match(wb.DocumentText, "Status: ([^\(]*)", RegexOptions.IgnoreCase)
    59. If (a(nrID).Success) Then
    60. Key(nrID) = a(nrID).Groups(1).Value
    61. rtbErgebnisse.Text = rtbErgebnisse.Text & NewLine & strID & " - " & Key(nrID)
    62. rtbErgebnisse.Text = rtbErgebnisse.Text.Trim
    63. rtbErgebnisse.SelectionStart = rtbErgebnisse.Text.Length
    64. rtbErgebnisse.ScrollToCaret()
    65. End If
    66. '// Ende eigentliche Funktion
    67. End Sub
    68. Private Sub timAutoInsert_Tick(sender As Object, e As EventArgs) Handles timAutoInsert.Tick
    69. If Clipboard.GetText <> old Then
    70. rtbIDs.Text = rtbIDs.Text & Clipboard.GetText & NewLine
    71. rtbIDs.SelectionStart = rtbIDs.Text.Length
    72. rtbIDs.ScrollToCaret()
    73. Clipboard.Clear()
    74. old = Clipboard.GetText
    75. End If
    76. End Sub
    77. Private Sub chbCopy_CheckedChanged(sender As Object, e As EventArgs) Handles chbCopy.CheckedChanged
    78. If timAutoInsert.Enabled = True Then
    79. timAutoInsert.Enabled = False
    80. ElseIf timAutoInsert.Enabled = False Then
    81. Clipboard.Clear()
    82. old = Clipboard.GetText
    83. timAutoInsert.Enabled = True
    84. End If
    85. End Sub
    86. End Class


    MultiVersion - Mit je einem Webbrowser pro Abfrage:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Environment
    3. Public Class Main
    4. Public wb(500) As WebBrowser
    5. Public a(500) As Match
    6. Public Key(500) As String
    7. Dim SW As New Stopwatch
    8. Dim old As String
    9. Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    10. Clipboard.Clear()
    11. old = Clipboard.GetText
    12. timAutoInsert.Enabled = True
    13. End Sub
    14. Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    15. ClearIDList()
    16. For i As Integer = 0 To rtbIDs.Lines.Count - 1
    17. wb(i) = New WebBrowser
    18. wb(i).ScriptErrorsSuppressed = True
    19. Next
    20. For i As Integer = 0 To rtbIDs.Lines.Count - 1
    21. wb(i).Navigate("http://payangocard.de/session/new")
    22. Next
    23. Thread.Sleep(200)
    24. Do Until wb(rtbIDs.Lines.Count - 1).IsBusy = False AndAlso
    25. wb(rtbIDs.Lines.Count - 1).ReadyState = WebBrowserReadyState.Complete ' #
    26. Während Browser Lädt
    27. Loop
    28. For i As Integer = 0 To rtbIDs.Lines.Count - 1
    29. wb(i).Document.GetElementById("login").InnerText = "*"
    30. wb(i).Document.GetElementById("password").InnerText = "*"
    31. wb(i).Document.Forms(0).InvokeMember("submit")
    32. Next
    33. Do Until wb(rtbIDs.Lines.Count - 1).DocumentText.Contains("Mein Account")
    34. Loop
    35. For i As Integer = 0 To rtbIDs.Lines.Count - 1
    36. GetState(rtbIDs.Lines(i).ToString, i)
    37. Next
    38. End Sub
    39. Private Sub rtbIDs_TextChanged(sender As Object, e As EventArgs) Handles rtbIDs.TextChanged
    40. lblIDCount.Text = "Zu prüfende IDs: " & rtbIDs.Lines.Count
    41. End Sub
    42. Private Sub ClearIDList()
    43. '// Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    44. If rtbIDs.Text.Contains("https://payangocard.de/admin/orders/") Then
    45. rtbIDs.Text = rtbIDs.Text.Replace("https://payangocard.de/admin/orders/", "")
    46. End If
    47. Thread.Sleep(50)
    48. rtbIDs.Refresh()
    49. rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Length > 0 Select s).ToArray
    50. ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1)
    51. Thread.Sleep(50)
    52. rtbIDs.Refresh()
    53. If rtbIDs.Text.Contains(" ") Then
    54. rtbIDs.Text = rtbIDs.Text.Replace(" ", "")
    55. End If
    56. Thread.Sleep(50)
    57. rtbIDs.Refresh()
    58. rtbIDs.SelectionStart = 0
    59. rtbIDs.ScrollToCaret()
    60. Thread.Sleep(50)
    61. rtbIDs.Refresh()
    62. '// Ende Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    63. End Sub
    64. Private Async Sub GetState(ByVal strID As String, ByVal nrID As Integer)
    65. '// eigentliche Funktion
    66. Await wb(nrID).NavigateTaskAsync("https://payangocard.de/admin/orders/" & strID)
    67. a(nrID) = Regex.Match(wb(nrID).DocumentText, "Status: ([^\(]*)", RegexOptions.IgnoreCase)
    68. If (a(nrID).Success) Then
    69. Key(nrID) = a(nrID).Groups(1).Value
    70. rtbErgebnisse.Text = rtbErgebnisse.Text & NewLine & strID & " - " & Key(nrID)
    71. rtbErgebnisse.Text = rtbErgebnisse.Text.Trim
    72. rtbErgebnisse.SelectionStart = rtbErgebnisse.Text.Length
    73. rtbErgebnisse.ScrollToCaret()
    74. Await wb(nrID).NavigateTaskAsync("https://payangocard.de/logout")
    75. Thread.Sleep(4000)
    76. wb(nrID).Dispose()
    77. End If
    78. '// Ende eigentliche Funktion
    79. End Sub
    80. Private Sub timAutoInsert_Tick(sender As Object, e As EventArgs) Handles timAutoInsert.Tick
    81. If Clipboard.GetText <> old Then
    82. rtbIDs.Text = rtbIDs.Text & Clipboard.GetText & NewLine
    83. rtbIDs.SelectionStart = rtbIDs.Text.Length
    84. rtbIDs.ScrollToCaret()
    85. Clipboard.Clear()
    86. old = Clipboard.GetText
    87. End If
    88. End Sub
    89. Private Sub chbCopy_CheckedChanged(sender As Object, e As EventArgs) Handles chbCopy.CheckedChanged
    90. If timAutoInsert.Enabled = True Then
    91. timAutoInsert.Enabled = False
    92. ElseIf timAutoInsert.Enabled = False Then
    93. Clipboard.Clear()
    94. old = Clipboard.GetText
    95. timAutoInsert.Enabled = True
    96. End If
    97. End Sub
    98. End Class



    evtl. seh ich ja für lauter Bäumen den wald nich :P
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

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

    Öhm ... mal was anderes: Dass picoflops NavigateTaskAsync bereits ne Async-Methode ist, weißt Du ja schon -> sie returnt (für Deinen Fall zu) früh und löst das DocumentCompleted-Event aus, wenn fertig. Aber Du reagierst doch gar nicht darauf. Stattdessen wartest Du mit ner Do...Loop-Schleife, dass die NavigateTaskAsync tatsächlich fertig -> Designfehler, da picoflop es damals erstellte, damit eben keine Warteschleifen mehr verwendet werden müssen.
    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.
    @VaporiZed ja , daran wird es wohl liegen, aber ich weis nicht wie ich sonst darauf warten kann das die Seite fertig geladen ist, denn mit :

    VB.NET-Quellcode

    1. Do Until wb.IsBusy = False AndAlso wb.ReadyState = WebBrowserReadyState.Complete ' # Während Browser Lädt
    2. Loop


    bleibt er einfach ewig in der Schleife hängen, (auch oben bei der Anmeldung) und das obwohl die Seite fertig ist ! (hab testweise die Form vergrößert und den WB als sichtbare Control eingebaut, selbst wenn die Seite geladen ist und auch komplett dargestellt wird, bleibt er in der schleife hängen...

    Und:

    VB.NET-Quellcode

    1. Await wb.Navigate("https://payangocard.de/admin/orders/" & strID)


    funktioniert leider nicht, dann wäre das mit dem Async ja auch wieder überflüssig oder nicht ?

    edit: habe jetzt

    VB.NET-Quellcode

    1. 'unter die navigation:
    2. WaitForPageLoad()
    3. 'irgendwo in die Klasse
    4. #Region "Page Loading Functions"
    5. Private Property pageready As Boolean = False
    6. Private Sub WaitForPageLoad()
    7. AddHandler wb.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    8. While Not pageready
    9. Application.DoEvents()
    10. End While
    11. pageready = False
    12. End Sub
    13. Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
    14. If wb.ReadyState = WebBrowserReadyState.Complete Then
    15. pageready = True
    16. RemoveHandler wb.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    17. End If
    18. End Sub
    19. #End Region


    gefunden, so arbeitet er aber wieder link für link ab.. ich glaub am sinnvollsten wäre es fast die hauptfunktion als fertige exe einfach mit dem Link als parameter zu starten (hab das so mal bei nem Docx zu PDf umwandler gemacht) dann funktioniert wenigstens alles zeitgleich und ohne probs, wenn es auch zugegebenermaßen nicht sehr performant ist und auch nicht sauber, aber naja so läufts immerhin mit mehreren Parallel ^^

    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

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

    Uff. Hab mir mal aus meinem Baustellen-Music-Play-Beispiel und der Extension von picoflop was zusammengebastelt. Das hängt auch schon ziemlich fest. Da hängt das WebBrowser-CE wohl hinterher - trotz Async.
    Aber mal was anderes:
    Do Until wb(rtbIDs.Lines.Count - 1).IsBusy = False AndAlso wb(rtbIDs.Lines.Count - 1).ReadyState = WebBrowserReadyState.Complete
    Ist das Absicht? Da wird drauf gewartet, dass der letzte WB in der Liste fertig ist, bevor alles andere mit den anderen WB-Instanzen weitergeht.
    Achso, und statt an Deine GetState-Prozedur einen WB-Index zu übergeben, gib doch die WB-Instanz selber weiter. Macht die Sache etwas einfacher. Und statt n WB-Array (500 ???) zu erzeugen, mach doch ne List(Of WebBrowser). Die lässt sich dynamisch bearbeiten. OK, hat alles nix mit dem Hauptproblem zu tun, aber: "Mühsam erhängt sich das Eichhörnchen"

    EDIT: Deinen Edit-Code kann ich nicht nachvollziehen. Wenn das Dokument fertig geladen ist, wird PageWaiter aufgerufen. OK. Aber ist dann das Auslesen von ReadyState noch notwendig? Zum anderen: Was passiert, wenn pageready True wird? Es wird wieder auf False gestellt. :huh:
    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 1 mal editiert, zuletzt von „VaporiZed“ ()

    also erstmal möchte ich dir auf jeden fall für deine Hilfe Danken und auch für deine Geduld ! =)
    also die Zeile

    VB.NET-Quellcode

    1. Do Until wb(rtbIDs.Lines.Count - 1).IsBusy = False AndAlso wb(rtbIDs.Lines.Count - 1).ReadyState = WebBrowserReadyState.Complete

    wurde anhand des Beispiels in menem letzten Post ersetzt

    und zwecks der List, das ist eine der vielen Sachen bei denen ich schon ettliche Stunden mit verbracht habe, aber ich steig da einfach nicht dahinter, selbst bei Arrays und co. test ich einfach so lang rum bis es halt läuft :P
    bei AutoIt (damit hab ich vor Jahren angefangen) wäre das alles viel leichter, da kann man die einzelnen Variablen mal eben dynamisch bennenen/erstellen und benötigt keine Arrays und co.
    also z.B.

    VB.NET-Quellcode

    1. For i = 1 to 10
    2. VarName&i = new webbrowser
    3. next


    wie es nochmal genau war, da müsst ich die alten scripte rauskrammen, aber als veranschaulichung reicht das denk ich ma ^^

    naja es ist schade das mein Program wohl nicht parallel arbeiten kann, aber naja da es für die Arbeit ist kann es ja auch ein wenig länger brauchen

    zu deinem Edit: kann ich dir leider nicht beantworten, A : kam der Code als eines der ersten google ergebnisse raus und scheint super zu funktionieren und B: addHandler sind auch so ne Sache mit denen ich nicht klar komme
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Also gut, dann erstmal eine Lösungsfokussierung. Gibt man einem WebBrowser alles zum Abarbeiten, hat der ne halbe Ewigkeit zu tun, da er nur eine Seite nach der anderen schafft. Multiprogrammstartlösung: naja. -> x Webbrowser-Instanzen für x Aufrufe.
    Mir ist da noch was eingefallen: Nimm nicht den WebBrowser, sondern ein neuen CE, was von WebBrowser erbt; nennen wir ihn mal WebBrowserEx (WBEx). Der hat dann noch ne zusätzliche Propertiy/Variable, die den Status des WBEx angibt. Dann könntest Du mit einem DocumentCompleted für alle WBEx-Instanzen prüfen, wie der Status ist und musst dann nicht immer neu das NavigateTaskAsync aufrufen und dann doch mit Do-Loop warten.
    Konzeptcode:

    VB.NET-Quellcode

    1. Dim WBExList As New List(Of WebBrowserEx)
    2. '...
    3. Dim NewWBEx As New WebBrowserEx
    4. AddHandler NewWBEx.DocumentCompleted, AddressOf DocIsLoadedCompletely
    5. WBExList.Add(NewWBEx)
    6. '...
    7. Private Sub DocIsLoadedCompletely(sender As Object, korrekte Rest-Signatur einfügen)
    8. Dim CurrentStatusOfSender = DirectCast(sender, WebBrowserEx).Status
    9. If CurrentStatusOfSender = LoadInitSite Then
    10. ElseIf CurrentStatusOfSender = MakeCrazyStuff Then
    11. End If
    12. End Sub

    dann würde der EventHandler jedes Mal aufgerufen werden, wenn die jeweilige WBEx-Instanz mit einer Seite fertig ist und könnte dann unterschiedlich agieren. Die Async-Programmierung kann man dann noch dranhängen.
    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.
    hm ?
    Dann könntest Du mit einem DocumentCompleted für alle WBEx-Instanzen prüfen, wie der Status ist und musst dann nicht immer neu das NavigateTaskAsync aufrufen und dann doch mit Do-Loop warten.


    du hattest doch weiter oben gesagt das das NavigateAsync mir nix bringt weil es zu früh irgendwas returnt oder nich ?

    des weiteren ist in dem Besipiel "MultiVersion - Mit je einem Webbrowser pro Abfrage:" aus Post 8 doch schon der Versuch unternommen worden jeder Seite einen eigenen Browser zu geben - mit dem resultat das es dennoch nicht funktioniert hat...

    und
    Nimm nicht den WebBrowser, sondern ein neuen CE, was von WebBrowser erbt; nennen wir ihn mal WebBrowserEx


    webbrowserEx findet das Studio nicht, was muss ich denn dafür importieren ?


    Edit:

    und wenn ich

    VB.NET-Quellcode

    1. Dim NewWBEx As New WebBrowserEx
    2. AddHandler NewWBEx.DocumentCompleted, AddressOf DocIsLoadedCompletely
    3. WBExList.Add(NewWBEx)


    richtig interpretiere, müsst ich ja auch wieder jeden Browser von Hand erstellen, bennennen und einfügen, Dynamisch benennen kann man dabei ja nicht, dazu benötigt man ja wieder ein array, also warum nicht gleich ein array ?

    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

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

    So, dann nochmal etwas konkretisiert. Um picoflops Extension kommt man wohl nicht vorbei, man kann aber eine eigene Reaktion auf das Fertigladen eines Dokuments noch ergänzen.
    Spoiler anzeigen

    WebBrowserEx ist, wie (wohl leider nur) angedeutet, ein eigenes Konstrukt. Ein WebBrowser mit Zusatzmerkmalen:

    VB.NET-Quellcode

    1. Friend Class WebBrowserEx : Inherits WebBrowser
    2. Friend Property Status As Integer
    3. End Class


    VB.NET-Quellcode

    1. Imports System.Diagnostics
    2. Public Class Main
    3. Private WBExList As New List(Of WebBrowserEx) 'dynamische Liste von WBEx
    4. Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles BtnStart.Click
    5. CreateListOfWBEx()
    6. LoadAllSites()
    7. End Sub
    8. Private Sub CreateListOfWBEx()
    9. Dim NewWBEx As WebBrowserEx = Nothing, Index = 0
    10. For Each Line In RtbIDs.Lines
    11. NewWBEx = New WebBrowserEx 'neuen WBEx erstellen
    12. NewWBEx.Status = 0
    13. NewWBEx.Name = "WBEx" & Index ' ! dynamisch Namen setzen !
    14. NewWBEx.ScriptErrorsSuppressed = True
    15. AddHandler NewWBEx.DocumentCompleted, AddressOf DocLoadedCompletely 'neben picoflops Code wird noch DocLoadedCompletely aufgerufen, wenn der jeweilige WBEx soweit mit seiner Seite ist
    16. WBExList.Add(NewWBEx) 'zur Liste hinzufügen
    17. Index += 1 'ok, konterkariert die For Each-Schleife, aber ist ja erstmal ein Entwurf
    18. Next
    19. End Sub
    20. Private Sub DocLoadedCompletely(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
    21. Dim CurrentWBEx = DirectCast(sender, WebBrowserEx) '= die WBEx-Instanz, die mit ihrer Seite fertig wurde
    22. Dim StatusOfCurrentWBEx = CurrentWBEx.Status
    23. Select Case StatusOfCurrentWBEx
    24. Case 0
    25. CurrentWBEx.Document.GetElementById("login").InnerText = "*"
    26. CurrentWBEx.Document.GetElementById("password").InnerText = "*"
    27. CurrentWBEx.Document.Forms(0).InvokeMember("submit")
    28. CurrentWBEx.Status = 1
    29. GetState(CurrentWBEx, "")
    30. Case 1
    31. Debug.Print(CurrentWBEx.Name & " finished at " & DateTime.Now.ToString)
    32. End Select
    33. End Sub
    34. Private Async Sub LoadAllSites()
    35. For Each WBEx In WBExList
    36. Debug.Print(WBEx.Name & " starts at " & DateTime.Now.ToString)
    37. Await WBEx.NavigateTaskAsync("http://payangocard.de/session/new")
    38. Next
    39. End Sub
    40. Private Async Sub GetState(WBEx As WebBrowserEx, strID As String)
    41. Await WBEx.NavigateTaskAsync("https://payangocard.de/admin/orders/" & strID)
    42. End Sub
    43. End Class


    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.
    @VaporiZed Wow, beeindruckender Code ! ich verstehe zwar leider nicht was genau dabei von statten geht, aber diesen Code konnte ich soweit nachvollziehen das ich Ihn wenigstens entsprechend anpassen konnte,
    folgender Maßen :

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Environment
    2. Imports System.Text.RegularExpressions
    3. Public Class Main
    4. Private WBExList As New List(Of WebBrowserEx) 'dynamische Liste von WBEx
    5. Dim old As String
    6. Dim swElapsed As New Stopwatch
    7. Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. Clipboard.Clear()
    9. old = Clipboard.GetText
    10. timAutoInsert.Enabled = True
    11. End Sub
    12. Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
    13. btnStart.Enabled = False
    14. btnRestart.Enabled = False
    15. ClearIDList()
    16. CreateListOfWBEx()
    17. LoadAllSites()
    18. End Sub
    19. Private Sub rtbIDs_TextChanged(sender As Object, e As EventArgs) Handles rtbIDs.TextChanged
    20. lblIDCount.Text = "Zu prüfende IDs: " & rtbIDs.Lines.Count
    21. End Sub
    22. Private Sub ClearIDList()
    23. '// Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    24. '/gehört zusammen
    25. rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Length > 0 Select s).ToArray
    26. ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1)
    27. '/gehört zusammen
    28. rtbIDs.Text = Regex.Replace(rtbIDs.Text, "[^0-9 \n]*", "")
    29. rtbIDs.Refresh()
    30. rtbIDs.SelectionStart = 0
    31. rtbIDs.ScrollToCaret()
    32. rtbIDs.Refresh()
    33. '// Ende Id - Liste, leere Zeilen und leerzeichen entfernen ,falls vorhanden URL entfernen
    34. End Sub
    35. Private Sub CreateListOfWBEx()
    36. Dim NewWBEx As WebBrowserEx = Nothing, Index = 0
    37. For Each Line In rtbIDs.Lines
    38. NewWBEx = New WebBrowserEx 'neuen WBEx erstellen
    39. NewWBEx.Status = 0
    40. NewWBEx.strLine = rtbIDs.Lines(Index)
    41. NewWBEx.iLine = Index
    42. NewWBEx.Name = "WBEx" & Index ' ! dynamisch Namen setzen !
    43. NewWBEx.ScriptErrorsSuppressed = True
    44. AddHandler NewWBEx.DocumentCompleted, AddressOf DocLoadedCompletely 'neben picoflops Code wird noch DocLoadedCompletely aufgerufen, wenn der jeweilige WBEx soweit mit seiner Seite ist
    45. WBExList.Add(NewWBEx) 'zur Liste hinzufügen
    46. Index += 1 'ok, konterkariert die For Each-Schleife, aber ist ja erstmal ein Entwurf
    47. Next
    48. End Sub
    49. Private Sub DocLoadedCompletely(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
    50. Dim CurrentWBEx = DirectCast(sender, WebBrowserEx) '= die WBEx-Instanz, die mit ihrer Seite fertig wurde
    51. Dim StatusOfCurrentWBEx = CurrentWBEx.Status
    52. Select Case StatusOfCurrentWBEx
    53. Case 0
    54. CurrentWBEx.Document.GetElementById("login").InnerText = "*"
    55. CurrentWBEx.Document.GetElementById("password").InnerText = "*"
    56. CurrentWBEx.Document.Forms(0).InvokeMember("submit")
    57. CurrentWBEx.Status = 1
    58. GetState(CurrentWBEx, CurrentWBEx.strLine)
    59. Case 1
    60. End Select
    61. End Sub
    62. Private Async Sub LoadAllSites()
    63. For Each WBEx In WBExList
    64. Await WBEx.NavigateTaskAsync("http://payangocard.de/session/new")
    65. Next
    66. End Sub
    67. Private Async Sub GetState(WBEx As WebBrowserEx, strID As String)
    68. If swElapsed.IsRunning = False Then
    69. swElapsed.Start()
    70. End If
    71. Await WBEx.NavigateTaskAsync("https://payangocard.de/admin/orders/" & strID)
    72. Dim a As Match = Regex.Match(WBEx.DocumentText, "Status: ([^\(]*)", RegexOptions.IgnoreCase)
    73. If (a.Success) Then
    74. Dim key As String = a.Groups(1).Value
    75. rtbErgebnisse.Text = rtbErgebnisse.Text & NewLine & rtbIDs.Lines(WBEx.iLine) & " - " & key
    76. rtbErgebnisse.Text = rtbErgebnisse.Text.Trim
    77. rtbErgebnisse.SelectionStart = rtbErgebnisse.Text.Length
    78. rtbErgebnisse.ScrollToCaret()
    79. WBEx.Navigate("https://payangocard.de/logout")
    80. If rtbErgebnisse.Lines.Count = rtbIDs.Lines.Count Then
    81. lblTime.Text = "Finished in: " & swElapsed.Elapsed.Hours & ":" & swElapsed.Elapsed.Minutes & ":" & swElapsed.Elapsed.Seconds & ":" & swElapsed.Elapsed.Milliseconds
    82. swElapsed.Stop()
    83. swElapsed.Reset()
    84. btnRestart.Enabled = True
    85. Else
    86. lblTime.Text = "Elapsed: " & swElapsed.Elapsed.Hours & ":" & swElapsed.Elapsed.Minutes & ":" & swElapsed.Elapsed.Seconds & ":" & swElapsed.Elapsed.Milliseconds
    87. End If
    88. End If
    89. End Sub
    90. Private Sub timAutoInsert_Tick(sender As Object, e As EventArgs) Handles timAutoInsert.Tick
    91. If Clipboard.GetText <> old Then
    92. rtbIDs.Text = rtbIDs.Text & Clipboard.GetText & NewLine
    93. rtbIDs.SelectionStart = rtbIDs.Text.Length
    94. rtbIDs.ScrollToCaret()
    95. Clipboard.Clear()
    96. old = Clipboard.GetText
    97. End If
    98. End Sub
    99. Private Sub chbCopy_CheckedChanged(sender As Object, e As EventArgs) Handles chbCopy.CheckedChanged
    100. If timAutoInsert.Enabled = True Then
    101. timAutoInsert.Enabled = False
    102. ElseIf timAutoInsert.Enabled = False Then
    103. Clipboard.Clear()
    104. old = Clipboard.GetText
    105. timAutoInsert.Enabled = True
    106. End If
    107. End Sub
    108. Private Sub btnRestart_Click(sender As Object, e As EventArgs) Handles btnRestart.Click
    109. Application.Restart()
    110. End Sub
    111. End Class
    112. Friend Class WebBrowserEx : Inherits WebBrowser
    113. Friend Property Status As Integer
    114. Friend Property strLine As String
    115. Friend Property iLine As Integer
    116. End Class


    Das wird mir auf jeden Fall für künftige Projekte super weiterhelfen, bei diesem benötigt er so, dennoch knapp 30 % länger (bei 10 IDs 17 Sekunden) als die alte Variante, entweder hab ich was falsch angepasst oder dem angepeilten Server schmecken mehrere Verbindungen zeitgleich nicht ^^

    Danke dir auf jeden Fall für die Hilfe =) 1A ^^
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    2 Kleinigkeiten, die mit dem eigentlichen Proglem leider nix zu tun haben:
    • Zeile 32, 33: Redim Preserve ist zum einen VB6-Style, zum anderen stellt sich die Frage, ob das Absicht ist, dass die letzte RtbID-gelöscht werden soll. Es sind doch nur noch nicht-leere Zeilen vorhanden
    • Deine StopWatch-Ausgabekonstruke lassen sich kürzen, z.B. lblTime.Text = "Finished in: " & swElapsed.Elapsed.ToString("hh\:mm\:ss\:ffff")
    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.

    VB.NET-Quellcode

    1. lblTime.Text = "Finished in: " & swElapsed.Elapsed.ToString("hh\:mm\:ss\:ffff")
    werd ich gleich übernehmen, ja sieht deutlich besser aus wenn da nicht so ne riesen Zeile steht, danke ^^

    und zum anderen, wenn ich beispielsweise eine leerzeile zwischen den einzelnen zeilen habe verbleibt diese, und diese PreDim geschichte is das einzige was ich fand um leere Zeilen zu verbannen, des weiteren wenn ich keine leerzeilen habe macht das PreDim doch gar nichts ? soweit ich das bislang feststellen konnte, entfernt es ausschlieslich leeren zeilen
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Oh nein, Gefahr im Verzug, da ReDim was anderes macht als Du denkst. Es verändert ein Array. Und zwar bei Deiner Zeile ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1) wird scheinbar* ein Array um eine Zeile gekürzt (und zwar egal, ob das Leerezilen sind oder nicht). ReDim verändert die Anzahl der Einträge. Und mit Deinem ReDim Preserve rtbIDs.Lines(rtbIDs.Lines.Count - 1) ist die letzte Zeile weg, was immer da auch stand. Daher solltest Du in Zeile 32 gleich erstmal noch Whitelines aussortieren, und zwar durch rtbIDs.Lines = (From s As String In rtbIDs.Lines Where s.Trim.Length > 0 Select s).ToArray, da s.Trim bei jeglichem s front- und end-Leerzeichen entfernt -> wenn ne Zeile nur aus Leerzeichen besteht, fliegt die raus. Und du brauchst Deine ReDim-Zeile nicht mehr - die eh was anderes machst, als Du denkst.

    *scheinbar deshalb, weil das eigentliche Array gar nicht verändert wird, sondern es wird ein neues erstellt und das alte verworfen, aber der Benutzer sieht trotz Preserve-Zusatz nur das gekürzte (oder auch verlängerte) Feld, welches er in die Funktion gesteckt hat
    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.
    @VaporiZed
    ist die letzte Zeile weg, was immer da auch stand.
    habs gerade mehrfach getestet, selbt wenn nur 1 Zeile Vorhanden ist, diese bleibt, die letzte verschwindet nicht, 3 Zeilen bleiben 3 Zeilen, drei Zeilen mit 2 leeren dazwischen = 3 zeilen
    ich meine ich passe es natürlich deinem Vorschlag entsprechend an, aber es ist dennoch so das die letzte zeile nicht verschwindet
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If