Ответ 1
httpWebRequest.Abort(); // before you leave
Буду решать!
Взгляните на ресурс.
Я пытаюсь получить серию файлов через HTTP, используя HttpWebRequest. Первый запрос проходит через штраф, но второй раз через тот же код GetResponse() зависает и время ожидания. WireShark показывает, что HTTP-трафик не отправляется для второго запроса, поэтому он выглядит как проблема API.
После некоторого расследования я обнаружил, что это связано с указанием длины содержимого: если я оставлю это, тогда код будет работать нормально.
Мой код:
HttpWebRequest httpWebRequest = ConfigureRequest();
using (WebResponse webResponse = httpWebRequest.GetResponse())
// On the second iteration we never get beyond this line
{
HttpWebResponse httpWebResponse = webResponse as HttpWebResponse;
using (Stream webResponseStream = httpWebResponse.GetResponseStream())
{
if (webResponseStream != null)
{
// Read the stream
}
}
statusCode = httpWebResponse.StatusCode;
httpWebResponse.Close();
}
Симптомы кажутся очень похожими на этот вопрос и на этот вопрос, но в обоих случаях приведенный совет заключается в том, чтобы избавиться от WebResponse, который я уже делаю.
Изменить В ответ на Gregory здесь ConfigureRequest():
private HttpWebRequest ConfigureRequest()
{
string sUrl = CreateURL(bucket, key);
HttpWebRequest httpWebRequest = WebRequest.Create(sUrl) as HttpWebRequest;
httpWebRequest.AllowWriteStreamBuffering = false;
httpWebRequest.AllowAutoRedirect = true;
httpWebRequest.UserAgent = this.m_sUserAgent;
httpWebRequest.Method = "GET";
httpWebRequest.Timeout = this.m_iTimeout;
// *** NB: This line was left out of my original posting, and turned out to be
// crucial
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
httpWebRequest.Headers.Add(StaticValues.Amazon_AlternativeDateHeader, timestamp);
httpWebRequest.Headers.Add(StaticValues.HttpRequestHeader_Authorization, StaticValues.Amazon_AWS + " " + aWSAccessKeyId + ":" + signature);
return httpWebRequest;
}
Изменить. Оказывается, я совершил кардинальный грех удаления кода из моего вопроса, который я не подтвердил, не был связан с проблемой. Я удалил следующие строки:
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
потому что я думал, что длина содержимого никогда не будет указана для запроса GET. Оказывается, я был неправ. Удаление этой строки устраняет проблему.
Единственный вопрос, который у меня сейчас возникает, почему? Я думаю, что указанная длина контента верна, хотя она может быть отключена одним. Будет ли указывать слишком длинную длину содержимого, чтобы предотвратить полную загрузку и заставить соединение оставаться открытым? Я бы ожидал, что Close() и/или Dispose() должны все равно убить соединение.
httpWebRequest.Abort(); // before you leave
Буду решать!
Взгляните на ресурс.
Убедитесь, что вы создаете новый HttpWebRequest каждый раз. Цитата из ссылки MSDN на GetResponse метод:
Несколько вызовов в GetResponse return один и тот же объект ответа; запрос не переиздается.
Обновление 1: ОК. Как насчет того, если вы попытаетесь закрыть webResponseStream тоже - вы в настоящее время этого не делаете, вы только закрываете webResponse (просто пытаетесь исключить ситуацию). Я также избавляюсь от httpWebResponse (а не только от WebResponse)
Обновление 2:
Единственное, что я могу предложить, это взглянуть на следующие статьи, на которые я смотрел, когда делал что-то похожее на то, что вы делаете:
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx
Единственные заметные вещи, которые я делаю, - это:
- установить webrequest.KeepAlive = false
- У меня нет файлов управления подключением в конфиге (я не зацикливаюсь, чтобы сделать серию запросов)
Документация для HttpWebRequest.ContentLength говорит:
Любое значение, отличное от -1 в свойстве ContentLength, указывает, что запрос загружает данные и что в свойстве Method могут быть установлены только те методы, которые загружают данные.
После того, как для свойства ContentLength установлено значение, это количество байтов должно быть записано в поток запросов, который возвращается путем вызова метода GetRequestStream или обоих методов BeginGetRequestStream и EndGetRequestStream.
Я подозреваю, что он зависает, потому что вы настраиваете длину контента, но не загружаете никаких данных. Можно было бы подумать, что в этом случае он должен сделать исключение, но, по-видимому, это не так.
Попробуйте использовать Plase:
HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
httpWebRequest.CachePolicy = noCachePolicy;
'Вам нужно инициализировать объекты webrequest и webresponse с допустимым URI:
Dim request As WebRequest = WebRequest.Create("http://google.com")
Dim response As WebResponse = request.GetResponse()
Function UrlExists(ByVal URL As String) As Boolean
Try
request = WebRequest.Create(URL)
response = request.GetResponse()
Catch ex As Exception
Return False
Finally
response.Close()
End Try
Return True
End Function