Je suis des produits de téléchargement par lots vers une base de données.
Je télécharge les URL de l'image sur le site à utiliser pour les produits. P>
Le code que j'ai écrit fonctionne bien pour les 25 premières itérations ( Toujours ce numéro pour une raison quelconque), mais me jette ensuite un système.net.webException "L'opération a expiré". p> J'ai vérifié l'URL distante qui demandait et C'est une URL de l'image valide qui renvoie une image. P> En outre, lorsque je le traverse avec le débogueur, je ne reçois pas l'erreur de délai d'attente. P> Aide! ;) p> p>
4 Réponses :
Si j'étais à votre place, voici quelques possibilités d'enquête: p>
Mon argent est sur ce dernier, puisque le fait qu'il se brise toujours à un beau nombre de demandes ronds et que le débogueur (aka plus lentement!) Ne déclenche pas le problème. P>
Pour tester tout cela, je commencerais avec la chose facile: Collez-vous dans un délai (thread.sleep) avant chaque appel HTTP et voyez si le problème disparaît. Si cela le fait, réduisez le retard jusqu'à ce que le problème revienne. Si ce n'est pas le cas, augmentez le retard jusqu'à un grand nombre (par ex. 10 secondes) jusqu'à ce que le problème disparaisse. Si cela ne disparaît pas avec un délai de 10 secondes, c'est vraiment un mystère et j'aurais besoin de plus d'informations pour diagnostiquer. p>
Si cela disparaît avec un retard, vous devez déterminer pourquoi ... et si la limite est permanente (pare-feu de Server par exemple que vous ne pouvez pas changer) ou quelque chose que vous pouvez changer. Pour obtenir plus d'informations, vous voudrez checter les demandes (par exemple, chèque DateTime .now avant et après chaque appel) pour voir si vous voyez un motif. Si les horaires sont tous cohérents et deviennent soudainement énormes, cela suggère un réseau de réseaux / pare-feu / proxy. Si les horaires augmentent progressivement, cela suggère un serveur que vous surchargez et allongez progressivement sa file d'attente de demande. p>
En plus de chronométrer les demandes, je définirais le délai d'attente de vos appels WebClient pour être plus long, de sorte que vous puissiez déterminer si le délai d'attente est infini ou juste un peu plus long que la valeur par défaut. Pour ce faire, vous aurez besoin d'une alternative à la classe WebClient, car elle ne prend pas en charge un délai d'attente. Ce fil sur Les forums MSDN ont un échantillon de code alternatif raisonnable. p>
Une alternative à ajouter de la synchronisation dans votre code consiste à utiliser Fiddler: P>
D'accord, cela ressemble vraiment à un problème de connexion de connexion. Cela pourrait également expliquer pourquoi le débogueur "corrige", car certaines connexions sont libérées pendant que le développement est assis dans le débogueur.
J'avais également recommandé d'utiliser "CARDPORTS" utilitaire ( NIRSOFT.net/utils/cports.htmlLec A>) qui affichera des connexions actuellement ouvertes dans une belle interface graphique (ou vous pouvez utiliser la commande NetStat "intégrée de Windows).
Augmenter le system.net.servicepointManager.defaultconnectionlimit code> a-t-il fait pour moi (j'utilise téléchargementfile code> dans les threads). Le Valeur par défaut < / a> est 2.
Il semble que I PROPSE que vous utilisez webclient code> ne ferme pas la réponse code> objet code> Il utilise une fois fait ce qui provoquera, dans votre cas, de nombreuses réponses à ouvrir en même temps et avec Une limite de 25 connexions sur le serveur distant, vous avez eu la «exception du délai d'attente». Lorsque vous déboguez, des réponses ouvertes précoces sont fermées en raison de leur délai intérieur, etc.
(I inpected webclient code> qu'avec le réflecteur, je ne trouve pas d'instruction pour la fermeture de la réponse). httpwebrequest & httpwebresponse code> afin que vous puissiez Nettoyer les objets après chaque téléchargement: p>
Voici une version légèrement simplifiée de la réponse de Manji:
private static void DownloadFile(Uri remoteUri, string localPath)
{
var request = (HttpWebRequest)WebRequest.Create(remoteUri);
request.Timeout = 30000;
request.AllowWriteStreamBuffering = false;
using (var response = (HttpWebResponse)request.GetResponse())
using (var s = response.GetResponseStream())
using (var fs = new FileStream(localPath, FileMode.Create))
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = s.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, bytesRead);
bytesRead = s.Read(buffer, 0, buffer.Length);
}
}
}
J'ai le même problème et je résous cela ajoutant ces lignes au fichier de configuration app.config:
Il semble que lorsque je traverse le débogueur, je ne reçois pas l'erreur de délai d'attente. Une raison pour laquelle?