webentwicklung-frage-antwort-db.com.de

System.Net.WebException: Der Vorgang ist abgelaufen

Ich habe ein großes Problem: Ich muss 200 Objekte auf einmal senden und Timeouts vermeiden.

while (true)
{

    NameValueCollection data = new NameValueCollection();
    data.Add("mode", nat);

    using (var client = new WebClient())
    {
        byte[] response = client.UploadValues(serverA, data);
        responseData = Encoding.ASCII.GetString(response);

        string[] split = Javab.Split(new[] { '!' },  StringSplitOptions.RemoveEmptyEntries);
        string command = split[0];
        string server = split[1];
        string requestCountStr = split[2];

        switch (command)
        {
            case "check":
                int requestCount = Convert.ToInt32(requestCountStr);

                for (int i = 0; i < requestCount; i++)
                {
                    Uri myUri = new Uri(server);
                    WebRequest request = WebRequest.Create(myUri);
                    request.Timeout = 200000;
                    WebResponse myWebResponse = request.GetResponse();
                }
                break;
        }
    }    
}

Dies erzeugt den Fehler:

Unhandled Exception: System.Net.WebException: The operation has timed out  
at System.Net.HttpWebRequest.GetResponse()  
at vir_fu.Program.Main(String[] args)

Die requestCount-Schleife funktioniert auch außerhalb meines Basiscodes, aber wenn ich sie meinem Projekt hinzufüge, erhalte ich diesen Fehler. Ich habe versucht, request.Timeout = 200; einzustellen, aber es hat nicht geholfen.

26
zimzim

Schließen/Entsorgen Sie Ihr WebResponse-Objekt.

33
Joe Chung

Es bedeutet, was es sagt. Die Operation hat zu lange gedauert.

Übrigens, schau auf WebRequest.Timeout und du siehst du hast dein Timeout für 1/5 Sekunde eingestellt.

32
John Saunders

Ich bin mir nicht sicher, in welchem ​​ersten Codebeispiel Sie WebClient verwenden. UploadValues: Es reicht nicht wirklich aus, um fortzufahren. Könnten Sie mehr von Ihrem umgebenden Code einfügen? In Bezug auf Ihren WebRequest-Code spielen hier zwei Dinge eine Rolle:

  1. Sie fordern nur die Header der Antwort **, lesen Sie niemals den Hauptteil der Antwort, indem Sie den ResponseStream öffnen und lesen (bis zu seinem Ende). Aus diesem Grund lässt der WebRequest-Client die Verbindung hilfreich offen und erwartet, dass Sie den Body jederzeit anfordern. Bis Sie den Antworttext bis zum Abschluss gelesen haben (wodurch der Stream automatisch geschlossen wird), den Stream bereinigen und schließen (oder die WebRequest-Instanz) oder warten, bis der GC seine Aufgabe erfüllt, bleibt Ihre Verbindung geöffnet.

  2. Sie haben standardmäßig eine maximale Anzahl von active -Verbindungen zu demselben Host von 2. Dies bedeutet, dass Sie Ihre ersten beiden Verbindungen aufbrauchen und sie nie wieder trennen, sodass Ihr Client nicht die Möglichkeit hat, die nächste Anforderung vorher auszuführen Es erreicht sein Timeout (Millisekunden, übrigens, also haben Sie es auf 0,2 Sekunden gesetzt - der Standard sollte in Ordnung sein).

Wenn Sie den Inhalt der Antwort nicht wünschen (oder gerade etwas hochgeladen oder gepostet haben und keine Antwort erwarten), schließen Sie einfach den Stream oder den Client, wodurch der Stream für Sie geschlossen wird.

Die einfachste Möglichkeit, dies zu beheben, besteht darin, sicherzustellen, dass Sie Blöcke für Einwegobjekte verwenden:

for (int i = 0; i < ops1; i++)
{
    Uri myUri = new Uri(site);
    WebRequest myWebRequest = WebRequest.Create(myUri);
    //myWebRequest.Timeout = 200;
    using (WebResponse myWebResponse = myWebRequest.GetResponse())
    {
        // Do what you want with myWebResponse.Headers.
    } // Your response will be disposed of here
}

Eine andere Lösung besteht darin, 200 gleichzeitige Verbindungen zu demselben Host zuzulassen. Wenn Sie jedoch nicht vorhaben, diesen Vorgang mit mehreren Threads auszuführen, so dass Sie mehrere gleichzeitige Verbindungen benötigen, hilft Ihnen das nicht wirklich:

 ServicePointManager.DefaultConnectionLimit = 200;

Wenn Sie Timeouts im Code erhalten, versuchen Sie am besten, das Timeout außerhalb des Codes zu erstellen. Wenn Sie nicht können, liegt das Problem wahrscheinlich an Ihrem Code. Normalerweise verwende ich cURL oder einfach einen Webbrowser, wenn es sich um eine einfache GET-Anfrage handelt.

** In Wirklichkeit fordern Sie tatsächlich den ersten Datenblock aus der Antwort an, der die HTTP-Header enthält, sowie den Beginn des Hauptteils. Aus diesem Grund ist es möglich, HTTP-Header-Informationen (z. B. Content-Encoding, Set-Cookie usw.) vor dem Lesen aus dem Ausgabestrom zu lesen. Beim Lesen des Streams werden weitere Daten vom Server abgerufen. Die Verbindung von WebRequest zum Server bleibt so lange geöffnet, bis Sie das Ende dieses Streams erreichen (dh er wird geschlossen, da er nicht gesucht werden kann), manuell geschlossen oder entsorgt. Hier gibt es mehr dazu .

26

Ich erinnere mich, dass ich vor einiger Zeit das gleiche Problem mit WCF hatte, aufgrund der Menge der Daten, die ich weitergegeben hatte. Ich erinnere mich, dass ich die Timeouts überall geändert habe, aber das Problem bestand fort. Was ich schließlich tat, war die Verbindung als Stream-Anfrage zu öffnen, ich musste den Client und den Server wechseln, aber es funktioniert auf diese Weise. Da es sich um eine Stream-Verbindung handelte, las der Server bis zum Ende des Streams weiter.

0
Freddy

proxy-Problem kann dies verursachen. IIS web config hat dies eingefügt 

<defaultProxy useDefaultCredentials="true" enabled="true">
          <proxy usesystemdefault="True" />
        </defaultProxy>
0
Blue Clouds