2009-03-23 5 views
0

hier ist meine Methode:HttpWebRequest nicht spätestens nach dem dritten Aufruf

private static void UpdatePref(List<EmailPrefer> prefList) 
{ 
    if(prefList.Count > 0) 
    { 
     foreach (EmailPref pref in prefList) 
     { 
      UpdateEmailRequest updateRequest = new UpdateEmailRequest(pref.ID.ToString(), pref.Email, pref.ListID.ToString()); 
      UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest(); 

      if (updateResponse.Success) 
      { 
       Console.WriteLine(String.Format("Update Succsesful. ListID:{0} Email:{2} ID:{1}", pref.ListID, pref.Email, pref.ID)); 
       continue; 
      } 
      Console.WriteLine(String.Format("Update Unsuccessful. ListID:{0} Email:{2} ID:{1}\n", pref.ListID, pref.Email, pref.ID)); 
      Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage)); 
     } 

     Console.WriteLine("Updates Complete."); 
    } 
    Console.WriteLine("Procses ended. No records found to update"); 
} 

die Liste hat rund 84 gültige Datensätze, die es Schleifen und für eine API-Anfrage senden. Aber es stoppt beim 3. API-Aufruf und verarbeitet nur 2 der 84 Datensätze. Wenn ich debugge, um zu sehen, was passiert, sehe ich nur, dass es hier in meiner SendRequest-Methode aufhört, ohne einen Fehler auszuspucken. Es stoppt beim GetRequestStream und wenn ich dazu komme und versuche, weiter zu gehen, stoppt es einfach und meine Anwendung läuft ohne Fehler weiter!

HttpWebRequest request = CreateWebRequest(requestURI, data.Length); 
request.ContentLength = data.Length; 
request.KeepAlive = false; 
request.Timeout = 30000; 

// Send the Request 
requestStream = request.GetRequestStream(); 

wtf? Schließlich, wenn ich es laufen lasse, bekomme ich den Fehler "Die Operation hat abgelaufen". Aber warum sind dann die ersten 2 Anrufe durchgekommen und dieser hat ein Zeitlimit überschritten? Ich verstehe es nicht.

Auch eine zweite Frage. Ist es ineffizient, ein neues Objekt in meiner Foreach zum Senden und Empfangen zu erstellen? Aber so habe ich diese Klassen ausgedrückt und verlangt, dass eine E-Mail, ListID usw. erforderlich sind, um diese Art von API-Aufruf zu senden. Ich wusste einfach nicht, ob es gut oder nicht effizient ist, durch jede Iteration in der Foreach eine neue Instanz zu erstellen. Könnte normal sein, fühlte sich aber komisch und ineffizient für mich.

+0

hmm, ich musste Anfrage hinzufügen.Abort(); Schließt das so oder so? – user72603

+0

eigentlich brauchte ich das gar nicht. Ich musste die Antwort jedes Mal mit response.Close() schließen; Ich schätze, wenn Sie Massenanrufe durchführen, müssen Sie sie schließen, damit der nächste schnelle Anruf das Objekt wieder verwenden kann und nicht gebunden wird. – user72603

+0

so heißt es, es ist nicht gut, response.Close zu verwenden. Ich bin hier verloren. Soll ich stattdessen spülen? Ich verstehe das nicht. – user72603

Antwort

0

Eine Möglichkeit für das Timing ist, dass der Server, mit dem du sprichst, dich drosselt. Sie könnten versuchen, eine Verzögerung (eine Sekunde, vielleicht?) Nach jedem Update einzufügen.

Unter der Annahme, dass UpdateEmailRequest und UpdateEmailResponse irgendwie aus WebRequest und WebResponse bzw. abgeleitet werden, ist es nicht besonders ineffizient die Anfragen, die Art und Weise erstellen Sie es tun. Das ist ziemlich Standard. Beachten Sie jedoch, dass WebResponseIDisposable ist, was bedeutet, dass es wahrscheinlich nicht verwaltete Ressourcen zuweist, und Sie sollten es beseitigen - entweder durch Aufruf der Methode Dispose. Etwas wie folgt aus:

UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest(); 
try 
{ 
    if (updateResponse.Success) 
    { 
     Console.WriteLine(String.Format("Update Succsesful. ListID:{0} Email:{2} ID:{1}", pref.ListID, pref.Email, pref.ID)); 
     continue; 
    } 
    Console.WriteLine(String.Format("Update Unsuccessful. ListID:{0} Email:{2} ID:{1}\n", pref.ListID, pref.Email, pref.ID)); 
    Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage)); 
} 
finally 
{ 
    updateResponse.Dispose(); 
} 

Ich denke, es ist möglich, dass nicht der Antwortobjekte Entsorgung an den Server eine offene Verbindung hält, und der Server ist das Timing, weil Sie zu viele offene Verbindungen haben.

1

EDIT: Es scheint, dass Sie Ihre eigene Frage bereits in den Kommentaren beantwortet haben.

Ich habe keine persönlichen Erfahrungen mit diesem, aber es scheint, Sie müssen schließen Sie auf die HTTP-Web-Anfrage, nachdem Sie die Antwort abgerufen haben. Es gibt ein Limit von 2 für die Anzahl der offenen Verbindungen und die Verbindung wird nicht freigegeben, bis Sie Close(). Siehe http://blogs.msdn.com/feroze_daud/archive/2004/01/21/61400.aspx, die den folgenden Code enthält, um die Symptome zu demonstrieren, die Sie sehen.

for(int i=0; i < 3; i++) { 
     HttpWebRequest r = WebRequest.Create(“http://www.microsoft.com“) as HttpWebRequest; 
     HttpWebResponse w = r.GetResponse() as HttpWebResponse; 
    } 
+1

danke, ich landete auch nur in einer using-Anweisung, um es zu schließen. Ich überprüfe diesen Link. – user72603

Verwandte Themen