C# HttpWebRequest тайм-аут после двух ошибок сервера 500

После того как я сделал два 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:

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 не получал прерывание ()'ed. В блоке catch() я добавил httpRequest.abort(), теперь он работает правильно.

2 ответа

Решение

Я подозреваю, что это проблема:

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

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

Я предполагаю, что:

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

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

Другие вопросы по тегам