22. juli 2007 - 21:44Der er
6 kommentarer og 1 løsning
App fryser ved brug af "WebRequest"
Hej Har en funktion der returnere om et link eksistere.
Det kører fint, men når funktionen er blevet kaldt nogle gange, "10-20 gange" så fryser programmet.
Alt kører fint hvis jeg fjerner de 3 WebRequest linier.
Her er koden.
Function Online(ByVal UrlS As String) As String Try Dim Url As New System.Uri(UrlS) Dim req As WebRequest = WebRequest.Create(Url) Dim resp As WebResponse = req.GetResponse() Catch Return False End Try Return True End Function
Et webrequest tager tid; og nogle gange mere end andre. Det er nok det du oplever.
Det mest sandsynlige er, at du kører Online funktionen på samme tråd som GUI tråden. Så er vinduet blokeret, og bliver ikke opdateret mens funktionen kører. Løsningen er at køre den i en separat tråd; eller bruge den asynkronve version af WebRequest.GetResponse (BeginGetResponse). (Asynkron kald er også at køre i en anden tråd, her gør frameworket bare det meste af arbejdet for dig).
Tror du tildels har ret, men det giver mig 2 nye spørgsmål.
1. Funktionen kaldes ud fra en ListBox og en timer, så den hvert 30 sek. tjekker det første Url i listboksen og derefter flytter Url'en ned i bunden, sådan kører det konstant.
Kan problemet så være at den ikke når at få response før timeren tricker igen?
2. Hvordan laver jeg evnt. funktionen om til at køre i en seperat tråd? Hvis jeg kan det, kan jeg jo fjerne timeren og så bare køre kontinuerligt med en sleep() i funktionen.
1. Det er muligt. Eller, det kan være serveren svarer langsommere nu-og-da.
2. Den nemmeste måde at lade funktionen køre kontinuerligt, ville være, at lade en tråd fra ThreadPool'en køre en metode, der gør arbejdet. Pseudo-VB agtigt:
Fra din form, f.eks. i OnLoad, starter du tråden: ThreadPool.QueueUserWorkItem(checkingFunction) Her er checkingFunction en delegate der peger på din metode. Den kan så se cirka således ud: While(condition) CheckIfStuffIsOnline Thread.Sleep(30000) End While
Der er lige et par udfordringer her. Dels skal du sikre at funktionen returnerer når dit program bliver lukket. I pseudo eksemplet herover kunne det gøres ved at lade condition bliver false. Endelig, når du skal opdatere elementer på din form, er det vigtigt at det gøres på GUI tråden og ikke på din anden tråd. Det gør du ved at bruge Invoke metoden - et eksempel findes på MSDN, ellers er Google din ven.
Jeg har ikke postet et færdigt eksempel da jeg normalt skriver C# og helt sikkert ville rode for meget rundt i VB syntaksen, til at det ville være nyttigt.
Takker for tippet, men har fået det til at spille på en noget mere simpel måde!
Function Online(ByVal UrlS As String) As String Try Dim Url As New System.Uri(UrlS) Dim req As WebRequest = WebRequest.Create(Url) Dim resp As WebResponse = req.GetResponse() NY LINIE resp.Close() Catch Return False End Try Return True End Function
Ærgeligt at skulle lede så længe efter en så SIMPEL ting :-)
Du får sku´ point for din indsats.
Tror måske jeg vil prøve den sidste løsning du kom med.
Du skal selvfølgelig lukke responset; den havde jeg ikke lige set. Ellers har du 10-20 åbne forbindelser til serveren, og så svarer den før eller senere langsomt eller slet ikke.
Som du selv skriver, bør du nok overveje tråd funktionen alligevel; idet dit GUI per definition ikke bliver opdateret mens funktionen kører.
Endelig vil jeg anbefale at du laver en Finally blok og flytter din resp.Close() derned. Så vil den altid blive kørt, selv hvis GetResponse smider en exception.
Det der står i en finally blok bliver altid kørt, uanset om der sker en exception i try blokken. Således kan du sikre oprydning af ressourcer, selvom der sker en exception.
Function Online(ByVal UrlS As String) As String Try Dim Url As New System.Uri(UrlS) Dim req As WebRequest = WebRequest.Create(Url) Dim resp As WebResponse = req.GetResponse()
Catch Return False Finally resp.Close() End Try Return True End Function
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.