Réglage de HttpWebRequest Timeout de la Connexion en C#
Je crois qu'après de longues recherche et de la recherche, j'ai découvert que ce que je veux faire, c'est probablement mieux servi par l'établissement d'une connexion asynchrone et à la fin après le délai désiré... Mais je vais aller de l'avant et demander de toute façon!
Rapide extrait de code:
HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(url);
webReq.Timeout = 5000;
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
//this takes ~20+ sec on servers that aren't on the proper port, etc.
J'ai un HttpWebRequest
méthode qui est dans une application multi-thread, dans lequel je me connecte à un grand nombre de société de serveurs web. Dans le cas où le serveur ne répond pas, le HttpWebRequest.GetResponse()
prend environ 20 secondes pour le temps, même si j'ai spécifié un délai d'attente de 5 secondes. Dans l'intérêt de passer par les serveurs sur un intervalle régulier, je veux ignorer ceux qui prennent plus de 5 secondes pour se connecter à.
La question est donc: "Est-il un moyen simple de spécifier/diminution d'un délai d'attente de connexion pour un WebRequest ou HttpWebRequest?"
Vous devez vous connecter pour publier un commentaire.
Je croire que le problème est que la
WebRequest
mesure le temps seulement après que la demande est faite. Si vous soumettez plusieurs demandes à la même adresse, alors leServicePointManager
sera l'accélérateur de vos demandes et de ne soumettre que de nombreuses connexions simultanées que la valeur du correspondantServicePoint.ConnectionLimit
qui, par défaut, obtient la valeur deServicePointManager.DefaultConnectionLimit
. Application CLR accueil jeux 2, ASP hôte à 10. Donc, si vous avez une application multithread qui soumet plusieurs demandes pour le même hôte, seulement deux sont réellement placés sur le fil, les autres sont mis en attente.Je n'ai pas fait des recherches pour une preuve concluante si c'est vraiment ce qui se passe, mais sur un projet similaire, j'avais des choses terribles jusqu'à ce que j'ai enlevé le
ServicePoint
limitation.Un autre facteur à considérer est la recherche DNS du temps. De nouveau, c'est ma croyance qui ne repose pas sur des preuves tangibles, mais je pense que le
WebRequest
ne pas compter de la recherche DNS du temps contre de l'expiration du délai de demande. DNS lookup temps peut apparaître comme très grand facteur temps sur certains déploiements.Et oui, vous devez le code de votre application autour de la
WebRequest.BeginGetRequestStream
(pourPOST
s avec le contenu) etWebRequest.BeginGetResponse
(pourGET
s etPOSTS
s). Des appels synchrones ne sera pas à l'échelle (je ne vais pas entrer dans les détails du pourquoi, mais je ne avoir des preuves tangibles pour). De toute façon, leServicePoint
question est orthogonal à cela: la mise en attente du comportement qui se passe avec les appels asynchrones trop.Désolé pour virer de bord à un vieux thread, mais je pense que quelque chose qui a été dit ci-dessus peut être incorrecte ou trompeuse.
De ce que je peux dire .Délai d'attente n'est PAS le temps de connexion, c'est la durée TOTALE autorisée pour toute la durée de vie de la HttpWebRequest et de la réponse. La preuve:
J'Ai Mis:
La connexion et l'heure de la HttpWebRequest a pris 26ms
mais l'appel HttpWebRequest.GetResponse() a expiré en 4974ms, prouvant ainsi que la 5000ms a été le délai pour toute demande d'envoi/obtenir de réponses d'appels.
Je n'ai pas vérifier si la résolution de nom DNS a été mesurée dans le cadre de la fois que cela est sans importance pour moi, car rien de tout cela fonctionne de la façon dont j'ai vraiment besoin de travailler mon intention était de le temps plus vite lors de la connexion à des systèmes qui n'étaient pas d'accepter les connexions comme indiqué par leur faute lors de la phase de connexion de la demande.
Par exemple: je suis prêt à attendre 30 secondes sur une demande de connexion qui a une chance de retourner un résultat, mais je ne veux graver 10 secondes d'attente pour envoyer une demande à un hôte qui est défaillante.
Chose que j'ai trouvé plus tard, ce qui a aidé, est le
.ReadWriteTimeout
de la propriété. Ceci, en plus de la.Timeout
propriété semblait enfin de réduire le temps threads serait passer à essayer de le télécharger à partir d'un serveur qui pose problème. Le temps par défaut pour.ReadWriteTimeout
est de 5 minutes, ce qui pour ma demande était beaucoup trop long.Donc, il me semble:
.Timeout
= temps passé à essayer d'établir une connexion (non compris les temps de recherche).ReadWriteTimeout
= temps passé à essayer de lire ou d'écrire des données une fois la connexion établiePlus d'infos: HttpWebRequest.ReadWriteTimeout Propriété
Edit:
Par @KyleM du commentaire, le
Timeout
propriété est pour l'ensemble de la tentative de connexion, et à la lecture sur à MSDN montre:(C'est moi qui souligne.)
.Timeout
propriété ne semble pas réellement englober l'intégralité de la réponse. J'ai eu un reproductible sous-ensemble de sites distants qui a permis d'établir rapidement et puis coulait hors du corps de la page de données à une vitesse très lente. Cela a causé des connexions à dépasser facilement plusieurs minutes au total, en dépit de moi réglage.Timeout
à 10 secondes. Mais dès que j'ai aussi set.ReadWriteTimeout
à 10 secondes, puis l'ensemble de la connexion interrompue, comme souhaité au bout de 10 secondes se sont écoulées.À partir de la documentation de la HttpWebRequest.Propriété Timeout:
Est-il possible que votre requête DNS est la cause de l'attente?
Peu importe ce que nous avons essayé nous n'avons pas réussi à obtenir le délai d'attente de moins de 21 secondes lorsque le serveur nous étions vérification a été vers le bas.
Pour contourner cela, nous avons combiné un TcpClient vérifier pour voir si le domaine était vivant suivie par un chèque séparé pour voir si l'URL a été active