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
после успешного или неудачного чтения.