Тайм-аут C # HttpWebRequest после двух ошибок сервера 500 - PullRequest
16 голосов
/ 27 октября 2010

После того как я сделал два C # HttpWebRequest, которые выдают исключение из-за «(500) Внутренняя ошибка сервера 500», третья попытка выдает исключение тайм-аута.Почему не выдается еще одно (500) внутреннее исключение «Ошибка сервера»?

При перезапуске приложения выдается две ошибки 500, а затем снова начинается тайм-аут.

Этомой код:

GetPages GetPages = new GetPages();
string test = GetPages.GetPage(); /* Exception: (500) Internal Server Error */
GetPages.Dispose();

GetPages GetPages = new GetPages();
string test = GetPages.GetPage();  /* Exception: (500) Internal Server Error */
GetPages.Dispose();

GetPages GetPages = new GetPages();
string test = GetPages.GetPage();  /* Exception: time out, why? */
GetPages.Dispose();

Это класс GetPages и метод GetPage:

namespace MyNamespace
{
    class GetPages
    {
        public string GetPage()
        {
            this.httpRequest = (HttpWebRequest)WebRequest.Create("http://myurl");

            try
            {
                StringBuilder postData = new StringBuilder(100);
                postData.Append("test=test");
                byte[] dataArray = Encoding.UTF8.GetBytes(postData.ToString());

                httpRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                httpRequest.KeepAlive = false;
                httpRequest.Proxy = null;
                httpRequest.Method = "POST";
                httpRequest.Timeout = 10;
                httpRequest.ContentType = "application/x-www-form-urlencoded";

                httpRequest.ContentLength = dataArray.Length;

                using (this.requestStream = httpRequest.GetRequestStream())
                {
                    requestStream.Write(dataArray, 0, dataArray.Length);
                    requestStream.Flush();
                    requestStream.Close();

                    this.webResponse = (HttpWebResponse)httpRequest.GetResponse();

                    Stream responseStream = webResponse.GetResponseStream();
                    StreamReader responseReader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
                    String responseString = responseReader.ReadToEnd();


                    MessageBox.Show(responseString);
                    return responseString;
                }
            }

            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return "FAIL";
            }
        }

        public void Dispose()
        {
            System.GC.SuppressFinalize(this);
        }
    }
}

ОБНОВЛЕНИЕ

Спасибо всем за помощь.Я не смог решить эту проблему.

Метод утилизации исчез.

Я сделал HttpWebRequest httpRequest, HttpWebResponse webResponse и Stream requestStream локально и используюследующие операторы использования:

using (webResponse = (HttpWebResponse)httpRequest.GetResponse())
{
    using (Stream responseStream = webResponse.GetResponseStream())
    {
        using (StreamReader responseReader = new System.IO.StreamReader(responseStream, Encoding.UTF8))
        {
            responseString = responseReader.ReadToEnd();
        }
    }
}

Еще одно обновление

Теперь это весь метод GetPage:

public string GetPage()
{
    HttpWebRequest httpRequest;
    HttpWebResponse webResponse;
    Stream requestStream;

    try
    {
        StringBuilder postData = new StringBuilder(100);
        postData.Append("test=test");
        byte[] dataArray = Encoding.UTF8.GetBytes(postData.ToString());

        httpRequest = (HttpWebRequest)WebRequest.Create("http://myurl");

        httpRequest.Proxy = null;
        httpRequest.Method = "POST";
        httpRequest.Timeout = 10;
        httpRequest.ContentType = "application/x-www-form-urlencoded";

        httpRequest.ContentLength = dataArray.Length;

        using (requestStream = httpRequest.GetRequestStream())
        {
            /* this is never reached when the time out exception starts 
            so the error seems to be related to too many GetRequestStreams */

            requestStream.Write(dataArray, 0, dataArray.Length);

            webResponse = (HttpWebResponse)httpRequest.GetResponse();

            /* this is never reached when the 500 server error occurs */

            String responseString = "";
            using (Stream responseStream = webResponse.GetResponseStream())
            {
                using (StreamReader responseReader = new System.IO.StreamReader(responseStream, Encoding.UTF8))
                {
                    responseString = responseReader.ReadToEnd();
                    return responseString;
                }
            }
        }
    }

    catch (Exception e)
    {
        return "FAIL";
    }

    return "...";
}

** РЕШЕНО !!** httpRequest не получал прерывание ().В блоке catch () я добавил httpRequest.abort (), теперь он работает правильно.

Ответы [ 2 ]

12 голосов
/ 27 октября 2010

I подозреваю вот в чем проблема:

this.webResponse = (HttpWebResponse)httpRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream, Encoding.UTF8);
String responseString = responseReader.ReadToEnd();

Вы не утилизируете ни один из этих одноразовых предметов.Это означает, что соединение с веб-сервером будет поддерживаться до завершения, поэтому пул соединений (из двух соединений на сервер) не будет разрешать другие запросы.

Я предлагаю:

  • Вы перемещаете вызов GetResponse из оператора using для потока запросов
  • Вы удаляете явные вызовы в Flush и Close для потока запросов (его удаление достаточно хорошо)
  • Вы создаете webResponse и webRequest локальные переменные вместо переменных экземпляра, если только вам действительно они не понадобятся позже, и в этом случае вы должны избавиться от них в своем методе Dispose.
  • Вы используете using операторы для WebResponse, Stream и StreamReader.(Последнее не является строго необходимым, поскольку удаление потока достаточно хорошо.)
  • Вы заставляете GetPages не реализовывать IDisposable, если вам это действительно не нужно.
7 голосов
/ 27 октября 2010

Протокол HTTP определяет, что только два соединения могут быть установлены одновременно к одному и тому же серверу. Закройте responseStream после успешного или неудачного чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...