HttpWebResponse застрять во время выполнения в цикле
Я строю этот метод (c#) для получения кода состояния ответа HTTP от URL. когда я запускаю этот метод, он работает нормально, но когда я запускаю его в цикле, в третий раз его застрял. есть зацепка??
public static string isAlive(string url)
{
Console.WriteLine("start: Is Alive Test");
WebRequest request = WebRequest.Create(url);
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return Convert.ToString((int)response.StatusCode);
}
catch(WebException ex)
{
HttpWebResponse res = (HttpWebResponse)ex.Response;
return Convert.ToString((int)res.StatusCode);
}
}
Петля
for (int i = 0; i < 5; i++)
{
string a = isAlive("https://www.yahoo.com/");
Console.WriteLine(a);
}
4 ответа:
Вы не вызываете
Dispose
на объектHttpWebResponse
, что означает, что соединение все еще лежит вокруг. Если вы измените свой код на следующий:public static string isAlive(string url) { Console.WriteLine("start: Is Alive Test"); WebRequest request = WebRequest.Create(url); try { using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { return Convert.ToString((int)response.StatusCode); } } catch(WebException ex) { using(HttpWebResponse res = (HttpWebResponse)ex.Response) { return Convert.ToString((int)res.StatusCode); } } }
Оператор
using
неявно вызовет Dispose для вас, который закроет соединение.Причина, по которой ваш код останавливается после второй итерации, заключается в том, что .Net имеет встроенное максимальное число соединений, которое он откроет для веб-сайта, что по умолчанию равно 2. Это контролируется
System.Net.ServicePointManager.DefaultConnectionLimit
, который вы можете увеличить должны вам нужно.
Это может быть связано с тем, что вы не закрываете HttpWebResponse. Добавим, наконец, что попробовать поймать, который закрывает ответ. Также закройте ответ WebException в catch.
Используйте "using", и это будет хорошо работать.
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { return Convert.ToString((int)response.StatusCode); }
- вам нужно обернуть
HttpWebResponse
var вusing
оператор, потому что он одноразовый- Перед проверкой
ex.Response.StatusCode
убедитесь, что ex.Статус -ProtocolError
- а также рассмотрите возможность сделать ваш метод асинхронным из соображений производительности
- поскольку ваш метод возвращает код состояния, для него может быть более подходящее имя, чем isAlive
Пример:
public static async Task<string> GetStatusCode(string url) { var request = (HttpWebRequest)WebRequest.Create(url); try { using (var response = (HttpWebResponse)await request.GetResponseAsync()) { return response.StatusCode.ToString(); } } catch (WebException ex) { return ex.Status == WebExceptionStatus.ProtocolError ? ((HttpWebResponse)e.Response).StatusCode.ToString() : null; } }