Auf Sub warten

  • VB.NET

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

    Auf Sub warten

    Hallo zusammen,
    ich programmiere zur Zeit ein kleines Hilfs Tool für den Browser und stehe vor einem Problem. Wenn ich mit dem Browser eine Seite aufrufe dann muss ich natürlich immer erst warten bis diese fertig geladen hab bevor mein Programm auf die Seite zugreifen kann, das mach ich mit folgenden Zeilen:

    VB.NET-Quellcode

    1. WebBrowser1.Navigate(URL)
    2. While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
    3. Application.DoEvents()
    4. End While


    Funktioniert auch wunderbar, jedoch führt das zu einem kleinem Problem. Ich rufe diese Funktion mehrmals über eine While Schleife von einem anderen Sub auf, wenn nun auf den Browser gewartet wird läuft die While Schleife fröhlich weiter und wartet nicht erst darauf das die Funktion beendet ist. Wie bekomme ich es hin das mein Prgramm erst dann weiter läuft wenn die Seite geladen ist?
    Indem du auf das DocumentCompleted-Event des Webbrowser-Elementes reagierst.
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.

    VB.NET-Quellcode

    1. While x < 10
    2. Seite_Laden
    3. x+=1
    4. End Whlie
    5. Fuction Seite_Laden
    6. WebBrowser1.Navigate(URL)
    7. While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
    8. Application.DoEvents()
    9. End While
    10. End Function


    So sieht theoratisch mein Code aus, wie soll ich da auf das Event reagieren? Ich kann ja nicht sagen wenn das Event kommt springe in die While Schleife von Sub XYZ beim x Wert bla.
    Mehr brauchst Du nicht:

    VB.NET-Quellcode

    1. Private started As Boolean = False
    2. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    3. WebBrowser1.Navigate(TextBox1.Text)
    4. started = True
    5. End Sub
    6. Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    7. started = False
    8. End Sub
    Ich will doch das meine Schleife weiter arbeitet.
    Wir arbeiten nicht mit DOS und auch nicht mit einer Console.
    Windows ist ein eventorientiertes Betriebssystem.
    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!

    VB.NET-Quellcode

    1. Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim rs As New ManualResetEvent(False)
    3. Dim hdl = Sub(o As Object,
    4. args As WebBrowserDocumentCompletedEventArgs)
    5. rs.Set()
    6. End Sub
    7. AddHandler WebBrowser1.DocumentCompleted, hdl
    8. Await (New Tasks.TaskFactory).StartNew(Sub()
    9. WebBrowser1.Navigate("www.heise.de")
    10. rs.WaitOne()
    11. End Sub)
    12. Debug.Print("done")
    13. End Sub

    Eisvogel schrieb:

    Das geht glaube ich schon eher in die Richtung was ich machen möchte
    Und dann kommst Du mit Fehlern, weil Du das ganze nicht verstehst und schon gar nicht beherrschst.
    Lass es sein.
    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!
    aber geht das nicht auch irgendwie einfacher?

    k.a.

    So funktioniert es, der Programmflow bleibt bestehen und der UI Thread wird nicht blockiert. Das ist also ein Ü-Ei ... Gleich DREI Sachen auf einmal ;)

    Der Webbrowser ist halt nicht der Knaller was die Einbindung in .Net angeht. Dem Webclient etc hat man ja TaskAsync Methoden spendiert, aber den WB hat man außen vor gelassen (vermutlich weils ActiveX ist)

    EDIT: Wäre doch mal ne schöne Erweiterungsmethode. Webbrowser.NavigateTaskAsync ... :) Dann hätte das ständige "While DoEvents" endlich mal ein Ende ...

    EDIT2:
    Also ICH find's einfach ;)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Imports System.Runtime.CompilerServices
    3. Imports System.Threading.Tasks
    4. Public Class Form1
    5. Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. For Each url In {"www.heise.de", "www.microsoft.com", "www.bmw.de"}
    7. Debug.Print("going to " & url)
    8. Await WebBrowser1.NavigateTaskAsync(url)
    9. Debug.Print("in " & url)
    10. Next
    11. End Sub
    12. End Class
    13. Public Module WebbrowserExtension
    14. <Extension()>
    15. Public Async Function NavigateTaskAsync(wb As WebBrowser, url As String) As Task
    16. Dim rs As New ManualResetEvent(False)
    17. Dim hdl = Sub(o As Object,
    18. args As WebBrowserDocumentCompletedEventArgs)
    19. rs.Set()
    20. End Sub
    21. AddHandler wb.DocumentCompleted, hdl
    22. Await (New Tasks.TaskFactory).StartNew(Sub()
    23. wb.Navigate(url)
    24. rs.WaitOne()
    25. End Sub)
    26. RemoveHandler wb.DocumentCompleted, hdl
    27. End Function
    28. End Module

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

    Wenn ich den Code richtig verstanden habe dann reicht es um eine Url aufzurufen diese Funktion zu verwenden:

    VB.NET-Quellcode

    1. Await WebBrowser1.NavigateTaskAsync(url)

    Das wäre genau das was ich machen will, jetzt kommt nur noch der Fehler:

    Es können nicht alle erforderlichen Typen für den 'Async'-Modifizierer gefunden werden.



    Vielleicht benutzt du eine andere VB Version als ich? Ich habe VisualStudio 2012 RS

    Eisvogel schrieb:

    Ich habe VisualStudio 2012 RS

    Du musst entweder 4.5 als Target nehmen oder für 4.0 das Async Target Pack runterladen
    microsoft.com/en-us/download/details.aspx?id=29576

    @ThuCommix:
    Du kannst auch einfach das Event benutzen...? ;o

    Dann kriegste aber keinen "linearen" Ablauf mehr hin. DAS ist ja gerade der große Vorteil von await. Der Code wird (optisch) sequentiell abgearbeitet, auch wenn im Hintergrund was ganz anderes passiert.

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