2016-10-14 4 views
0

J'ai une application qui envoie des demandes au même serveur REST constamment et après un certain temps HttpWebRequest.GetResponse() commence à expirer J'ai remarqué que chaque fois que j'augmente System.Net.ServicePointManager. DefaultConnectionLimit Cela prend plus de temps pour recommencer à chronométrer, ce qui devrait signifier que ces requêtes restent actives, mais autant que je sache, je les ferme toutes.HttpWebRequest.GetResponse() expire après un certain temps

Voici la méthode que j'utilise pour mes demandes.

actuelle DefaultConnectionLimit est à 10.

Aussi il y a 1 demande qui se passe pendant la majeure partie de la vie des applications.

J'utilise .NET Compact Framework et le serveur REST est écrit en utilisant WCF (4.5 .NET)

public static string HttpRequest(string request, string method, string contentType, int timeout) 
    { 
       string result = ""; 
       HttpWebRequest req = (HttpWebRequest)WebRequest.Create(PodesavanjaManager.TrenutnaPodesavanja.PutanjaServisa + "/" + request); 
       req.Method = method; 
       req.ContentType = contentType; 
       req.Timeout = timeout; 
       req.KeepAlive = false; 
       if(method == "POST") 
        req.ContentLength = 0; 
       using(Stream stream = req.GetResponse().GetResponseStream()) 
       { 
        using(StreamReader reader = new StreamReader(stream)) 
        { 
         result = reader.ReadToEnd(); 
         reader.Close(); 
        } 
        stream.Close(); 
        stream.Flush(); 
       } 
       return result; 
     } 

EDIT nouvelle version de la méthode:

public static string HttpRequest(string request, string method, string contentType, int timeout) 
{ 

    string result = ""; 
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(PodesavanjaManager.TrenutnaPodesavanja.PutanjaServisa + "/" + request); 
    req.Method = method; 
    req.ContentType = contentType; 
    req.Timeout = timeout; 
    req.KeepAlive = false; 


    if(method == "POST") 
     req.ContentLength = 0; 
    using (HttpWebResponse resp =(HttpWebResponse) req.GetResponse()) 
    { 
     using (Stream stream = resp.GetResponseStream()) 
     { 
      using (StreamReader reader = new StreamReader(stream)) 
      { 
       result = reader.ReadToEnd(); 
       reader.Close(); 
      } 
     } 
    } 
    GC.Collect(); 
    return result; 
} 
+0

Pourquoi utilisez-vous stream.Close et Flush à l'intérieur en utilisant (stream) .. L'utilisation va automatiquement fermer et disposer le flux. Je n'utiliserais pas et j'aurais le contrôle total pour pouvoir utiliser Close et Flush. Ajoutez une demande explicite req.Dispose() et req = null à la fin. Dans une autre question SO GC.Collect(); GC.WaitForPendingFinalizers(); est utilisé pour forcer l'objet à disposer. – josef

+0

Je suis d'accord pour dire que vous n'avez pas besoin à la fois de 'Close' et' using', mais j'utiliserais personnellement la variante 'using' - toute exception garderait la connexion en cours d'utilisation sans une gestion correcte des erreurs. Et 'Flush' après' Close' semble un peu étrange. –

+0

Oui c'était mon mauvais, mais à la fin de l'utilisation du bloc à la fois devrait se produire de toute façon, je les ai tous enlevés, de toute façon j'ai mis à jour avec une nouvelle version de ma méthode. – Aleksandar

Répondre

0

Je suis d'accord qu'il ne se comportent comme la connexion est toujours utilisée par une ressource qui n'a pas été fermée. Le documentation pour HttpWebResponse mentions:

Vous devez appeler soit la Stream.Close ou la méthode HttpWebResponse.Close pour fermer la réponse et libérer la connexion pour la réutilisation. Il n'est pas nécessaire d'appeler à la fois Stream.Close et HttpWebResponse.Close, mais cela ne provoque pas d'erreur.

J'espérais une description plus simple comme « vous devez soit fermer le flux retourné par GetResponseStream ou appeler la méthode HttpWebResponse.Close -. Mais si mon interprétation de la documentation est correcte, votre code est bien

nous utilisons HttpWebRequest dans nos applications cE ainsi, et toujours mettre la réponse dans un bloc using aussi bien - vous pouvez essayer ceci:

using(HttpWebResponse response = (HttpWebResponse)req.GetResponse()) 
using(Stream stream = response.GetResponseStream()) 
{ 
    // ... 
} 

avez également vous vérifié votre code pour d'autres HttpWebRequest usages, juste pour être sûr?

+0

J'ai essayé de faire cela il y a quelques heures, en obtenant toujours des délais d'attente, j'ai remarqué que les délais d'attente se produisent lorsque j'envoie plusieurs demandes l'une après l'autre avec la version actuelle de ma méthode. – Aleksandar