Кто-нибудь знает, почему я получаю тайм-аут HttpWebRequest?

Мне было интересно, можете ли вы помочь мне с ошибкой, которая у меня есть. У меня есть HTTP-менеджер, который я создал, который помогает мне обрабатывать данные POSTing/GETing с веб-сайтов. Он работал нормально до недавнего времени, когда я пытаюсь использовать смесь обоих. В первом цикле все работает, во втором цикле зависает на HttpWebRequest.GetRequestStream(). Я прочитал всю сеть и не нашел реального решения. Ниже приведены кодовые блоки для выборки/получения:

 ASCIIEncoding encoding = new ASCIIEncoding();
 byte[] buffer = encoding.GetBytes(_PostData);

_HttpWebRequest = (HttpWebRequest)WebRequest.Create(_FetchUrl);
_HttpWebRequest.Credentials = _Credentials;
_HttpWebRequest.Method = _RequestType.ToString();
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
_HttpWebRequest.ContentLength = buffer.Length;
_HttpWebRequest.UserAgent = userAgent;
_HttpWebRequest.CookieContainer = _CookieContainer;
_HttpWebRequest.KeepAlive = false;
_HttpWebRequest.AllowAutoRedirect = _AllowAutoRedirect;
_HttpWebRequest.AutomaticDecompression = DecompressionMethods.GZip;
_HttpWebRequest.ServicePoint.Expect100Continue = false;  

 if (_RequestType.Equals(RequestTypes.POST))
{
     // Write POST
 Stream reqStream = _HttpWebRequest.GetRequestStream();
 {
  reqStream.Write(buffer, 0, buffer.Length);
  reqStream.Flush();
  reqStream.Close();
    }
}

И ответ:

HttpWebResponse httpWebResponse = (HttpWebResponse)_HttpWebRequest.GetResponse();
{
  Stream responseStream = httpWebResponse.GetResponseStream();
  {
    if (_UseGzip)
    {
      if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
      {
        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
      }
      else
      {
        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
      }
    }

    if (responseStream != null)
    {
      StreamReader streamReader = new StreamReader(responseStream);
      {
        try
        {
          _PageContent = streamReader.ReadToEnd();
        }
        finally
        {
          streamReader.Close();
          responseStream.Close();
          httpWebResponse.Close();
        }
      }
    }
    else
    {
      _PageContent = string.Empty;
    }
  }
}
_HttpWebRequest.Abort();

Может ли кто-нибудь увидеть какие-либо недостатки, почему мой код зависает? Все потоки закрываются, я установил разрешенные соединения более 100, я не понимаю, почему это ломается.


person Paul Oakham    schedule 11.02.2010    source источник
comment
Вы пытались использовать что-то вроде Wireshark, чтобы увидеть, какие данные на самом деле отправляются?   -  person Foole    schedule 11.02.2010
comment
Когда вы говорите, что код работает в первый раз, но останавливается во второй, какие методы http вы используете во время соответствующих запросов?   -  person Anders Fjeldstad    schedule 11.02.2010
comment
Код зависает в сообщении, GET работает нормально. Когда я запускаю код через прокси-сервер burp, он почему-то работает нормально? Возможно, прокси восстанавливает некоторые из моих заголовков, потому что я не понимаю, как это должно иметь значение.   -  person Paul Oakham    schedule 12.02.2010
comment
попробуйте ответ Джона, у меня возникла такая же проблема, как и у вас. удаление ресурса решило мою проблему.   -  person Benny    schedule 21.02.2010


Ответы (3)


Это может быть связано с тем, что вы не избавляетесь от своего WebResponse, потоков или StreamReaders:

var request = WebRequest.Create(...);
using (var response = request.GetResponse())
{
    using (var responseStream = response.GetResponseStream())
    {
        using (var reader = new StreamReader(responseStream))
        {
            // use the reader
        }
    }
}
person John Saunders    schedule 21.02.2010
comment
Я прерываю запрос (метод удаления недоступен) и закрываю все доступные потоки. Я также попытался установить для всех объектов значение null, а затем вызвать GC в конце каждого запроса, чтобы избавиться от них, и это также не повлияло. - person Paul Oakham; 23.02.2010
comment
@Paul: вам также нужно избавиться от StreamReader, так как он реализует IDisposable. То же самое с Stream, который вы не закрываете, если возникает исключение. Вот что делает для вас блок using. Он гарантирует, что его параметр Disposed, несмотря ни на что. Как только я слышу, что ваш код дает сбой при последующих попытках, мне интересно, что он не сделал при предыдущей попытке. Очень часто ответ заключается в том, что что-то не получилось Dispose'd. - person John Saunders; 23.02.2010

У меня такая же проблема. Я правильно закрыл (расположил) все потоки и HttpWebResponse с помощью этих блоков использования. Проблема все еще сохранялась, когда я спамил запросы, которые были прерваны ThreadAbortExceptions. Наконец, это помогло вызвать myWebRequest.Abort() при возникновении ThreadAbortException! Надеюсь это поможет.

person Sven Pohl    schedule 22.06.2011

Я вижу, что вы используете:

HttpWebRequest.AutomaticDecompression = DecompressionMethods.GZip;

Наряду с ручной декомпрессией:

      if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
      {
        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
      }
      else
      {
        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
      }

Не пробовал, если это действительно имеет значение, но я использую только ручной подход и в аналогичном коде, и он отлично работает. На самом деле у меня проблема с зависанием, но только с одним доменом, эксперименты со свойствами показали разницу.

О, и я подозреваю, что если вы не используете какое-либо сжатие почтовых данных, вам нужно удалить заголовок кодирования контента.

person Andrey Doloka    schedule 27.11.2013