web-dev-qa-db-fra.com

HttpWebRequest: la demande a été abandonnée: la demande a été annulée

Je travaille sur le développement d'une sorte d'intermédiaire, qui télécharge du texte sur un serveur CMS en utilisant des requêtes de publication HTTP pour une série de dates (généralement 7 à la fois). J'utilise HttpWebRequest pour accomplir cela. Cela semble fonctionner correctement pour la première date, mais lorsqu’il commence la deuxième date, j’obtiens la System.Net.WebException: la demande a été abandonnée: la demande a été annulée.

J'ai cherché autour et trouvé les gros indices suivants:

http://social.msdn.Microsoft.com/Forums/en-US/netfxnetcom/thread/0d0afe40-c62a-4089-9d8b-fb4d206434dc

http://www.jaxidian.org/update/2007/05/05/8

http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html

Et ils n'ont pas été trop utiles. J'ai essayé de surcharger GetWebReuqest mais cela n'a pas de sens car je n'utilise pas cette fonction.

Voici mon code: http://Pastebin.org/115268

J'obtiens l'erreur sur la ligne 245 après qu'elle a été exécutée avec succès au moins une fois.

J'apprécierais toute aide que je pourrais obtenir car c'est la dernière étape d'un projet sur lequel je travaille depuis quelque temps. C’est mon premier projet C #/VS, je suis donc ouvert à tous les conseils, mais j’aimerais me concentrer sur la résolution de ce problème en premier.

Merci!

20
Emeka

La solution commune répertoriée sur Internet semble être de définir la propriété KeepAlive de HttpWebRequest sur false. Cela peut résoudre le problème si la cause première est que la connexion doit être réutilisée même si elle a été fermée automatiquement après un certain temps. Cependant, les connexions sont constamment ouvertes et fermées.

Une autre solution possible que j'ai utilisée lorsque j'ai rencontré ce problème consistait à étendre les propriétés de délai d'attente: WebRequest.ReadWriteTimeout, WebRequest.Timeout, RequestStream.WriteTimeout et RequestStream.ReadTimeout. Veuillez noter que ces délais sont exprimés en millisecondes. Vous voudrez peut-être que les délais d'attente soient de 1000 * 60 * 10 pour représenter 10 minutes (ou tout simplement 600 000 si vous pensez savoir ce que cela signifie ...). Vous pouvez vérifier si cela est la cause la plus probable du problème en réduisant la taille du fichier.

BTW. Votre code n'était plus sur le site Web répertorié. Vous voudrez peut-être l'inclure dans le texte de votre message si le problème persiste.

18
Registered User

Voici la seule solution qui fonctionne pour moi:

http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx

Ces lignes sont la clé:

    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(yourUri);
    wr.KeepAlive = false;
    wr.Timeout = System.Threading.Timeout.Infinite;
    wr.ProtocolVersion = HttpVersion.Version10;

Et ici:

wr.AllowWriteStreamBuffering = false;
12
RoundOutTooSoon

Un bref résumé de mon application: J'ai jusqu'à 16 threads identiques effectuant des requêtes HTTP simultanées. Chacun de ces threads demande à différents serveurs Web avec des points de terminaison locaux uniques. Maintenant, la fonction effectuant ces appels a 3 requêtes HTTP successives à effectuer (sur le même serveur Web) et à effectuer une certaine agrégation.

Sur la base des solutions affichées dans les liens ci-dessus, la combinaison suivante a fonctionné pour moi.

System.Net.ServicePointManager.DefaultConnectionLimit = 200;
System.Net.ServicePointManager.MaxServicePointIdleTime = 2000;
System.Net.ServicePointManager.MaxServicePoints = 1000;
System.Net.ServicePointManager.SetTcpKeepAlive(false, 0, 0);

HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest1.KeepAlive = false;
webRequest1.Timeout = 2000;
//Do other stuff here...
//Close response stream

Thread.Sleep(1000); //This delay seems to help. Obviously very specific to the server

HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest2.KeepAlive = false;
webRequest2.Timeout = 2000;
//Do other stuff here...
//and so on...
3
tman

Je soutiens un service Web Azure qui accepte des fichiers de l'application mobile et les transfère vers le stockage d'objets blob Azure en copiant le flux de la demande entrante dans le flux d'un HttpWebRequest sortant, par ex. 

using (Stream requestStream = outgoingRequest.GetRequestStream()) 
{ 
    context.Request.InputStream.copyTo(requestStream)
    requestStream.Flush();
    requestStream.Close();
}

De temps à autre, il lançait l'exception "La demande a été annulée: la demande a été annulée" lors de Close () ou à la fin de l'utilisation de {} si vous n'incluez pas Close (). J'ai essayé toutes les solutions suggérées ci-dessus et aucune d'entre elles n'a fonctionné jusqu'à ce que j'ai trouvé la cause réelle de l'erreur que je voudrais partager ici: Parfois, le flux d'entrée de la requête entrante est coupé et ne contient pas le contenu complet du fichier. Lorsque ce flux incomplet est copié dans le flux de la demande sortante, la demande sortante génère une erreur lors du Close () ou à la fin du bloc using {}. C’est un peu trompeur puisque la cause n’est pas la requête sortante, mais
le flux incomplet y étant copié . Pour éviter cela, ajoutez une vérification de la longueur du flux de demandes entrantes comparant la longueur du fichier à stocker dans l'en-tête de l'application appelante, par exemple.

    if (context.Request.InputStream.Length != int.Parse(context.Request.Headers["file-length"])) 
    { 
        //handle this case here, e.g.
        context.Response.StatusCode = 500;
        context.Response.StatusDescription = "(500) Internal Server Error";
        context.Response.End();
    }
    else
    {
         //proceed with copying the stream (the first code snippet)
    }
0
user2116792