Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[VB.NET] Wachten tot url is geladen

Pagina: 1
Acties:

  • ikkuhqhp
  • Registratie: Oktober 2006
  • Laatst online: 14-11 09:45
Hoi,
Ik heb een programma waarbij ik in een functie, eerst waarde 1 moet posten en als dat gedaan is, dus als de document.completed is, dan pas verder. Ik weet dat dat gedaan kan worden met DocumentCompleted. Als je dat doet krijg je wel zo'n ontzettende zooi in je code en het wordt een pain om daarna weer de volgende waarde te posten. Ik heb even gegoogled en ik heb dit alternatief gevonden:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Private Sub loadURL(ByRef browser As WebBrowser, ByVal url As String)
      browser.Tag = "loading"
      browser.Navigate(url)
End Sub

MainBrowser.DocumentCompleted(ByVal..............)
     MainBrowser.Tag = "loaded"
End Sub

btnSearch_Click(ByVal......)
     loadURL(mainBrowser, "www.google.com")
     Do While mainBrowser.Tag = "loading"
          Application.DoEvents 'hierdoor zou de browser door moeten gaan met laden
     Loop

     ' do stuff
End Sub


Maar dat hij dus niet, hij blijft hangen bij die loop.

Mijn eigen code ter controle:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        If blok >= 2000 Then
            loadURL(WebAction3, "http://www.voorbeeld.nl", "koop=1&hoeveelheid=1")
            MsgBox("Blok is groter dan 2000")
            Do While WebAction3.Tag = "loading"
                Application.DoEvents()
            Loop
                Call blok()
            Exit Sub
        ElseIf volpas >= 3 Then
            MsgBox("Blokdoos2000 is meer dan 3")
            loadURL(WebAction3, "http://www.voorbeeld.nl", "verkoop=1&hoeveelheid=3")
            MsgBox("Url laden aangeroepen!")
            Do While WebAction3.Tag = "loading"
                'MsgBox("Dit is voor doEvents! En Tag is: " & WebAction3.Tag)
                System.Windows.Forms.Application.DoEvents()
                'MsgBox("Dit is na doEvents En Tag is: " & WebAction3.Tag)
            Loop
            MsgBox("3 kleine dozen verkocht!")
            loadURL(WebAction3, "http://www.voorbeeld.nl", "koop=2&hoeveelheid=1")
            Do While WebAction3.Tag = "loading"
                System.Windows.Forms.Application.DoEvents()
            Loop
            MsgBox("1 grotere doos gekocht!")
            Call blok()
            Exit Sub

Het DoEvents() doet het dus niet. Als je mijn code ziet snap je ook wel waarom ik liever niet met DocumentCompleted werk, hierna komt namelijk nog een paar keer van hetzelfde.

--edit--
ik vergat te zeggen dat hij de pagina dus helemaal niet meer laadt als DoEvents() erin staat. Als ik die loop wegglaat, dan laadt hij hem te laat, maar dan doet hij het in ieder geval wel. Nou loopt hij gewoon vast, je kan het programma niet eens meer normaal afsluiten!

Wie o wie kan mij nu weer helpen?

--edit2--
en, zoals het een tweaker betaamt, ben ik er alsnog achter gekomen. Na veel veel googlen vond ik:
Visual Basic:
1
2
3
4
5
6
            While (WebAction3.IsBusy = True)
                ' Theoretically we shouldn’t need this, but experience says otherwise.
                ' If we just bang on the IsBusy() method we will use up a lot of CPU time
                '  and probably bog down the entire computer.
                Application.DoEvents()
            End While

Dat lijkt te werken! Enige probleem is dat hij de waardes niet goed post, ik denk alleen niet dat het door deze loop komt!

[ Voor 15% gewijzigd door ikkuhqhp op 01-06-2008 19:46 ]


  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 17-11 13:12

sopsop

[v] [;,,;] [v]

Waarom gebruik je het browser component voor deze functionaliteit? M.a.w. wil je ook echt een browserscherm tonen of gebruik je het alleen om een post te doen?

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Het lijkt mij dat System.Net.WebClient idd een betere candidaad is.

Daarbij zou ik in je loop (regel 12-14) ook een System.Theads.Thread.Sleep opnemen.. DoEvents geeft namelijk de controle terug aan Windows om bijvoorbeeld de schermen te updaten (counters, progressbars, meldingen, etc). Een 'timeout' bij elke iteratie van 100ms (0,1 sec) is voor een gebruiker nauwelijks merkbaar. Nu krijgt jouw programma door de loop waarschijnlijk bijna geen executie tijd toegewezen omdat je deze direct weer terug geeft aan het OS.

If it isn't broken, fix it until it is..


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 13-10 22:03

MrSleeves

You'll thank me later.

Application.DoEvents is imo een method die je het liefst wilt vermijden. Het kan verleidelijk zijn om te gebruiken, zeker als je een VB6 achtergrond hebt; dan kan er namelijk een neiging zijn om meerdere threads te vermijden.

Ik zou je aanraden om zoiets in een BackgroundWorker te doen. Je hebt dan een aparte thread waar je tijdrovende code kan aanroepen en onderwijl blijft de rest gewoon actief.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • ATS
  • Registratie: September 2001
  • Laatst online: 29-10 18:37

ATS

Ik zou eens gaan overwegen om je code te herstructureren. Waarom maak je niet een lijst met URLs die je langs wil (en de bijbehorende messages), en gebruik je wél DocumentCompleted? Je dan op een DocumentCompleted dan gewoon het volgende item uit de lijst te halen en dat te verwerken, totdat je lijst leeg is. Dat lijkt me een stuk eleganter, en je hebt geen rare wacht-loopjes nodig met alle ellende van dien.

[ Voor 7% gewijzigd door ATS op 02-06-2008 16:08 ]

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • ikkuhqhp
  • Registratie: Oktober 2006
  • Laatst online: 14-11 09:45
Ik heb geen behoefte aan een echt browserscherm, dus de webclient voldoet ook, ik heb net op msdn gekeken naar de implementatie. Maar gaat de code dan vanzelf pas verder als de waardes zijn gepost? als ik bijvoorbeeld dit doe:
Visual Basic:
1
Dim responseArray As Byte() = myWebClient.UploadValues(uriString, "POST", myNameValueCollection)


wacht hij nu met verdergaan naar de volgende regel todat hij gepost heeft?
Wat betreft toch met documentCompleted werken, dat is eigenlijk geen optie, gezien de verdere code die gedraaid wordt (voorafgaand aan dit gedeelte)

en als laatste had ik dit dus nog gevonden:
Visual Basic:
1
2
3
4
5
6
            While (WebAction3.IsBusy = True)
                ' Theoretically we shouldn’t need this, but experience says otherwise.
                ' If we just bang on the IsBusy() method we will use up a lot of CPU time
                '  and probably bog down the entire computer.
                Application.DoEvents()
            End While


maar daar was ik niet heel erg tevreden over want het lijkt dat hij het dan maar één keer doet (kan ook aan de rest liggen)
maar ik ben zeer benieuwd naar de implementatie van myWebClient.UploadValues()!

In ieder geval al bedankt voor deze tips!

--edit--
ik vergeet wel te zeggen dat er wel ingelogd moet worden in een form, dus hij moet wel elke keer de cookie meesturen. Ik weet dat dat kan met WebClient.UploadValues(), dat zegt msdn namelijk ;) Maar hoe lees ik mijn cookie uit, uit een normale browser. (Die heb ik namelijk wel 1 van nodig. Daarmee log ik in via die post methode en browsed de user verder rond. Dus in principe kun je uit die browser altijd de cookie halen met o.a. de sessionID

[ Voor 15% gewijzigd door ikkuhqhp op 03-06-2008 00:11 ]


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Waarom gebruik je niet WebClient.UploadValuesAync()? Dan heb je geen rare while 'busy' loop nodig. Je code krijgt dan automatisch de 'focus' terug via het event UploadValuesComplete als de data is.

Zonder een timeout zijn while loops dodelijk voor je applicatie.

Wat betreft je login: Je doet toch al een PreAuthenticate? Als de website goed is ingesteld wordt je dan automatisch ingelogd (daarom stuur je tenslotte de gegevens mee) en krijg je dus een sessionid.

If it isn't broken, fix it until it is..


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Niemand_Anders schreef op dinsdag 03 juni 2008 @ 08:55:
Waarom gebruik je niet WebClient.UploadValuesAync()? Dan heb je geen rare while 'busy' loop nodig. Je code krijgt dan automatisch de 'focus' terug via het event UploadValuesComplete als de data is.
Met de synchrone versie heb je ook geen vreemde while loop nodig. Je moet alleen wel zorgen dat je het op een aparte thread ( Dus niet de GUI thread ) uitvoert zodat je GUI niet blijft hangen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

rwb schreef op dinsdag 03 juni 2008 @ 09:16:
[...]

Met de synchrone versie heb je ook geen vreemde while loop nodig. Je moet alleen wel zorgen dat je het op een aparte thread ( Dus niet de GUI thread ) uitvoert zodat je GUI niet blijft hangen.
De async methodes bieden je juist het gemak dat je niet zelf met threading aan de slag moet. Dan zelf via een background worker de synchrone methode aanroepen lijkt mij dan een beetje overbodig. Ik heb liever dat de CLR zoveel mogelijk voor mij regelt..

If it isn't broken, fix it until it is..


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Niemand_Anders schreef op dinsdag 03 juni 2008 @ 10:36:
[...]

De async methodes bieden je juist het gemak dat je niet zelf met threading aan de slag moet. Dan zelf via een background worker de synchrone methode aanroepen lijkt mij dan een beetje overbodig. Ik heb liever dat de CLR zoveel mogelijk voor mij regelt..
Daar ben ik het wel mee eens, je zei alleen dat je daardoor rare while loopjes kan vermijden, maar de synchrone versie heeft dat probleem ook niet.

Het is juist het asynchrone karakter van het webbrowser control waardoor de TS die vreemde loopjes heeft.

De TS zegt dat het in zijn geval niet mogenlijk is met Asynchrone methods, maar dat lijkt mij nogal sterk.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • ikkuhqhp
  • Registratie: Oktober 2006
  • Laatst online: 14-11 09:45
ik neig nu naar WebClient.UploadValuesAync(), want ik begrijp dat als ik bijvoorbeeld dit doe:
Visual Basic:
1
2
3
private sub post()
WebClient.UploadValuesAync("website","postwaardes") ' niet gelet op de werkelijke syntax!
msgbox(" Gepost")

De messagebox pas getoont wordt als de pagina geladen is. Dat is dus wat ik zocht, gezien de tweede request pas verzonden mag worden als de eerste is gedaan.

Maar wat mij nog niet helemaal duidelijk is, is of de cookies die door een WebBrowser object worden aangemaakt, ook gelijk worden meegestuurd met een request van een WebClient. Ik kan hier nu testen, gezien ik geen toegang heb tot een Visual Basic Design omgeving.

Zouden jullie mijn aanames willen verifieren?

Dank jullie voor deze vele hulp!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Nee de Messagebox word nu meteen getoond nadat gestart is met het uploaden van de values. Dat is het idee van Asynchrone methodes.

Maar waarom doe je niet iets als volgt

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void BtnClick(..)
{
      BeginSendItem();
}

void BeginSendItem()
{
     item = PopItemFromQueue();
     if(item != null)
     {
         myConnection.BeginPost( item, EndSendItem );
     }
}

void EndSendItem( AsyncResult result )
{
    try
    {
        myConnection.EndPost( result );
        BeginSendItem();
    }
    catch( SomeException )
    {
        //Something went wrong
    }
}

Op deze manier gebruik je Asynchrone methodes zoals het hoort ( Je moet even de juiste methodes opzoeken ) en blokeert je GUI thread ook niet

[ Voor 70% gewijzigd door Woy op 03-06-2008 11:43 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • sig69
  • Registratie: Mei 2002
  • Nu online
ikkuhqhp schreef op dinsdag 03 juni 2008 @ 11:30:
Maar wat mij nog niet helemaal duidelijk is, is of de cookies die door een WebBrowser object worden aangemaakt, ook gelijk worden meegestuurd met een request van een WebClient.
Welk WebBrowser object? Die gebruik je nu toch niet meer?
Een WebClient ondersteund in ieder geval geen cookies, maar dit is simpel zelf te implementeren door GetWebRequest te overriden.

[ Voor 3% gewijzigd door sig69 op 03-06-2008 11:48 ]

Roomba E5 te koop


  • ikkuhqhp
  • Registratie: Oktober 2006
  • Laatst online: 14-11 09:45
rwb, ik vind het makkelijker om gewoon WebClient.UploadValues te gebruiken. Het scheelt maar enkele miliseconden en zo is het heel makkelijk om te zorgen dat de volgende post pas begint als de 1e gedaan is:
Visual Basic:
1
2
3
WebClient.UploadValues(adres,postwaardes1)
'voer query 1 uit en voer daarna pas query 2 uit:.
WebClient.UploadValues(adres,postwaardes2)

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
ikkuhqhp schreef op dinsdag 03 juni 2008 @ 11:59:
rwb, ik vind het makkelijker om gewoon WebClient.UploadValues te gebruiken. Het scheelt maar enkele miliseconden en zo is het heel makkelijk om te zorgen dat de volgende post pas begint als de 1e gedaan is:
Visual Basic:
1
2
3
WebClient.UploadValues(adres,postwaardes1)
'voer query 1 uit en voer daarna pas query 2 uit:.
WebClient.UploadValues(adres,postwaardes2)
Als je altijd weet dat het snel gaat is dat wel makkelijk ja, echter kan het natuurlijk zo zijn dat een site niet snel reageert en dan krijg je opeens het idee dat je applicatie is vastgelopen!

Je zou het eventueel ook in een BackgroundWorker kunnen doen dan heb je dat probleem ook niet meer.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • ikkuhqhp
  • Registratie: Oktober 2006
  • Laatst online: 14-11 09:45
@sig69 Ik gebruik wél een browser object, dat is de UI, nu post ik deze waardes met andere, verborgen webbrowsers. Dus er is altijd 1 webborwser object!
@rwb: ik weet dat de website altijd snel reageert, daar maak ik me niet druk om. Vandaar dat ik denk dat WebClient.uploadValues() de beste optie is!
Pagina: 1