2017-08-08 2 views
0

Je veux rechercher sur un site Web pour les numéros à 4 chiffres et d'extraire un lien sur la page, qui contient ce numéro. Le code suivant fonctionne très bien:C# HttpWebResponse.GetResponse() se bloque lorsque je le mets dans une méthode

List<KeyValuePair<int, string>> urls = new List<KeyValuePair<int, string>>(); 
for (int index = 3000; index < 4000; index++) { 
    string url = "http://www.myurl.com/page?q=" + index.ToString(); 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

    if (response.StatusCode == HttpStatusCode.OK) { 
     Stream receiveStream = response.GetResponseStream(); 
     StreamReader readStream = null; 

     if (response.CharacterSet == null) { 
      readStream = new StreamReader(receiveStream); 
     } else { 
      readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet)); 
     } 

     string itemurl = ""; 
     while (!readStream.EndOfStream) { 
      string ln = readStream.ReadLine(); 
      int start = ln.IndexOf("https://www.myurl.com/" + index.ToString()); 
      if (start > -1) { 
       int stop = ln.IndexOf(".htm\"", start) + 4; 
       itemurl = ln.Substring(start, stop - start); 
       Console.Write(index + ", "); 
       urls.Add(new KeyValuePair<int, string>(index, itemurl)); 
       break; 
      } 
     } 
     response.Close(); 
     readStream.Close(); 
    } 
} 

Cependant, si je mets la partie contrôle (tout dans la boucle) dans une méthode qui renvoie l'URL:

string GetUrl(int index) { 
.. 
     //urls.Add(new KeyValuePair<int, string>(index, itemurl)); is replaced by: 
     return itemurl; 
.. 
    return ""; 
} 

J'appeler la méthode la boucle:

List<KeyValuePair<int, string>> urls = new List<KeyValuePair<int, string>>(); 
    for (int index = 3000; index < 4000; index++) { 
     string itemurl = GetUrl(index); 
     if(itemurl != "") urls.Add(new KeyValuePair<int, string>(index, itemurl)); 
    } 

Le programme va se bloquer exactement après que 2 URL ont été trouvées et je ne vois pas pourquoi cela se produit. Le blocage se produira à request.GetResponse(); J'ai essayé de régler le Timeout à 500 ms, attraper l'exception et réessayer un peu plus tard, mais je n'obtiendrai toujours pas de réponse. Je peux aussi rechercher d'autres numéros et le résultat est le même. Il va se bloquer après que deux URL ont été trouvées. J'ai essayé de basculer entre Release ou Debug, entre .NET 3.5, 4.0, 4.5, 4.6 et le résultat est le même. Je cours Windows 10, mais je l'ai également essayé sur un ordinateur distant exécutant 8.1 et une VM XP et ai obtenu la même chose.

Si je ne le place pas dans une méthode séparée, il vérifie 1000 nombres en moins d'une minute.

J'ai commencé à être vraiment contrarié par ce problème, donc toute aide serait grandement appréciée.

Répondre

0

Après plusieurs heures de difficultés, j'ai trouvé ce qui cause le problème, donc je vais partager la solution.

Le problème était que je n'appelais pas la méthode response.Close() lorsque je renvoyais une URL, donc elle utilisait toujours les ressources. Appeler cette méthode avant de revenir a résolu le problème. Une autre solution consiste à mettre le code dans un bloc using, comme:

using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()){ 
.. 
}