J'utilise une bibliothèque open source pour me connecter à mon serveur Web. Je craignais que le serveur Web ne soit extrêmement lent, puis j'ai essayé de faire un test simple en Ruby et j'ai obtenu ces résultats.
Programme Ruby: 2,11 secondes pour 10 HTTP GETs
Programme Ruby: 18,13 secondes pour 100 HTTP GETs
Bibliothèque C #: 20.81seconds pour 10 HTTP GETs
Bibliothèque C #: 36847.46 secondes pour 100 HTTP GETs
J'ai profilé et trouvé le problème être cette fonction:
private HttpWebResponse GetRawResponse(HttpWebRequest request) {
HttpWebResponse raw = null;
try {
raw = (HttpWebResponse)request.GetResponse(); //This line!
}
catch (WebException ex) {
if (ex.Response is HttpWebResponse) {
raw = ex.Response as HttpWebResponse;
}
}
return raw;
}
Il faut environ 1 seconde à la ligne marquée pour se terminer tandis que le programme Ruby qui fait une demande prend 0,3 seconde. Je fais également tous ces tests sur 127.0.0.1, donc la bande passante du réseau n'est pas un problème.
Qu'est-ce qui pourrait causer cet énorme ralentissement?
METTRE À JOUR
Découvrez les résultats de référence modifiés. En fait, j'ai testé avec 10 GET et non 100, j'ai mis à jour les résultats.
Ce que j’ai trouvé être le principal responsable des demandes Web lentes est la propriété proxy. Si vous définissez cette propriété sur null avant d'appeler la méthode GetResponse, la requête ignorera l'étape de détection automatique du proxy:
request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}
La détection automatique du proxy demandait jusqu'à 7 secondes avant de renvoyer la réponse. Il est un peu gênant que cette propriété soit définie par défaut pour l'objet HttpWebRequest.
Cela peut avoir à voir avec le fait que vous ouvrez plusieurs connexions à la fois. Par défaut, le nombre maximal de connexions HTTP ouvertes est défini sur deux. Essayez d'ajouter ceci à votre fichier .config et voyez si cela aide:
<system.net>
.......
<connectionManagement>
<add address="*" maxconnection="20"/>
</connectionManagement>
</system.net>
J'avais un problème similaire avec un projet MVC VB.Net.
Localement, sur mon ordinateur (Windows 7), il fallait moins d'une seconde pour accéder aux demandes de page, mais sur le serveur (Windows Server 2008 R2), il prenait plus de 20 secondes pour chaque demande de page.
J'ai essayé une combinaison de la définition du proxy à null
System.Net.WebRequest.DefaultWebProxy = Nothing
request.Proxy = System.Net.WebRequest.DefaultWebProxy
Et changer le fichier de configuration en ajoutant
<system.net>
.......
<connectionManagement>
<add address="*" maxconnection="20"/>
</connectionManagement>
</system.net>
Cela n'a toujours pas réduit les temps de demande de page lents sur le serveur. En fin de compte, la solution consistait à décocher l'option “Détecter automatiquement les paramètres” dans les options IE sur le serveur lui-même. (Sous Outils -> Options Internet, sélectionnez l’onglet Connexions. Appuyez sur le bouton Paramètres réseau.)
Immédiatement après avoir décoché cette option de navigateur sur le serveur, tous les temps de demande de page sont passés de 20 secondes à moins de 1 seconde.
J'ai commencé à observer un ralentissement similaire à celui de l'OP dans cette zone, qui s'est un peu amélioré avec l'augmentation du nombre de connexions maximales.
ServicePointManager.DefaultConnectionLimit = 4;
Mais après la construction de ce nombre de WebRequests, les retards sont revenus.
Le problème, dans mon cas, c’était que j’appelais un POST et que je ne me souciais pas de la réponse. Je n’avais donc rien à faire. Malheureusement, cela a laissé le WebRequest en suspens jusqu'à ce qu'ils aient expiré.
Le correctif consistait à prendre la réponse et à la fermer.
WebRequest webRequest = WebRequest.Create(sURL);
webRequest.Method = "POST";
webRequest.ContentLength = byteDataGZ.Length;
webRequest.Proxy = null;
using (var requestStream = webRequest.GetRequestStream())
{
requestStream.WriteTimeout = 500;
requestStream.Write(byteDataGZ, 0, byteDataGZ.Length);
requestStream.Close();
}
// Get the response so that we don't leave this request hanging around
WebResponse response = webRequest.GetResponse();
response.Close();
Utilisez un ordinateur autre que localhost, puis utilisez WireShark pour voir ce qui se passe réellement sur le réseau.
Comme d'autres l'ont dit, cela peut être un certain nombre de choses. Regarder les choses au niveau TCP devrait donner une image claire.
Je ne sais pas exactement comment je suis parvenu à cette solution, je n'ai pas encore eu le temps de faire des recherches, alors c'est à vous de décider. Il y a un paramètre et je l'ai utilisé comme ceci (chez le constructeur de ma classe, avant d'instancier l'objet HTTPWebRequest):
System.Net.ServicePointManager.Expect100Continue = false;
Je ne sais pas pourquoi, mais maintenant, mes appels semblent bien plus rapides.
Je sais que c'est un vieux fil, mais j'ai perdu toute la journée avec HttpWebRequest lent, j'ai essayé toutes les solutions fournies sans succès. Chaque demande d'adresse était supérieure à une minute.
Finalement, problème était lié à mon pare-feu antivirus (Eset). J'utilise un pare-feu avec le mode interactif, mais Eset a été complètement désactivé. Cela a permis à la demande de durer éternellement. Après activer Eset et exécuter la demande, le message Invite du pare-feu s'affiche et, après confirmation, demande s'exécuter pendant moins d'une seconde.
J'ai essayé toutes les solutions décrites ici sans succès, l'appel a pris environ 5 minutes.
Quel était le problème: J'avais besoin de la même session et évidemment des mêmes cookies (demande faite sur le même serveur), donc j'ai recréé les cookies de Request.Cookies dans WebRequest.CookieContainer . Le temps de réponse était d'environ 5 minutes.
Ma solution: Commenté le code relatif aux cookies et bam! L'appel a pris moins d'une seconde.
Pour moi, le problème était que j'avais installé LogMeIn Hamachi - ironiquement pour déboguer à distance le même programme qui avait alors commencé à afficher cette extrême lenteur.
Pour votre information, la désactivation de la carte réseau Hamachi n’était pas suffisante car il semble que son service Windows réactive la carte.
De plus, me reconnecter à mon réseau Hamachi n'a pas résolu le problème. Ne désactiver que l'adaptateur (en désactivant le service LogMeIn Hamachi Windows) ou, probablement, en désinstallant Hamachi, a résolu le problème pour moi.
Est-il possible de demander à HttpWebRequest
de sortir via une carte réseau spécifique?
Cela a fonctionné pour moi:
<configuration>
<system.net>
<defaultProxy erabled="false"/>
</system.net>
</configuration>