HttpWebRequest GetRequestStream SystemException после нескольких вызовов случайным образом
У меня есть программа на C# .NET 3.5 CompactFramework, которая запрашивает данные из C# WebService:
public SynchronisationResult<J> Get<J>(IEnumerable<DomainProxy> existingObjects, string controller, string parameters) where J : IdJsonObject)
{
string existingObjectsJson = JsonConvert.SerializeObject(existingObjects);
string url = GenerateUrl(controller, parameters);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "text/json";
request.Method = "POST";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version11;
request.Timeout = 60000;
request.ContentLength = existingObjectsJson.Length;
using (Stream requestStream = request.GetRequestStream())
{
using (var streamWriter = new StreamWriter(requestStream))
{
streamWriter.Write(existingObjectsJson);
streamWriter.Flush();
streamWriter.Close();
}
requestStream.Close();
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
string responseData = "";
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
responseData = streamReader.ReadToEnd();
}
if (response.StatusCode == HttpStatusCode.OK)
{
result = JsonConvert.DeserializeObject<SynchronisationResult<J>>(responseData);
}
else
{
throw new Exception(responseData);
}
response.Close();
}
}
Я могу вызывать этот метод несколько раз с разными параметрами (разные контроллеры на WebServer), и вдруг все застревает. Приложение больше не реагирует, когда я нажимаю PAUSE в Visual Studio, я вижу указатель программы на месте
using (Stream requestStream = request.GetRequestStream())
Иногда SystemException генерируется в Timer.ring System.Net.Connection..., хотя в этом случае приложение не продолжает работать, даже если всплывающее исключение для следующего catch-Block. Это означает, что мне нужно перезагрузить устройство, которое никогда не будет работать.
Я попытался следующие изменения, чтобы решить эту проблему:
- request.KeepAlive = true / false
- request.Pipelines = true / false
- ServicePointManager.DefaultConnectionLimit = 1000;
- request.AutomaticDecompression = DecompressionMethods.GZip или ничего
Ничего, запрос прекрасно работает в Почтальоне, например. Странно то, что если я реализую это в цикле for, запрашивая около 200 объектов для обновления, он быстрее падает. Если я реализую метод запроса по нажатию кнопки и щелкаю его с частотой около 10 секунд, он работает намного дольше. Я попытался с бэкэндом разработки IIS на порту 888, с рабочей машиной на порту 80, локальный брандмауэр отключен. Нет определенного запроса, который не может быть выполнен, это может быть запрос типа A, B или C,... каждый прогон отличается.
Кто-нибудь объяснит:
а) почему код застревает и не продолжается?
б) почему код застревает даже при возникновении исключения
c) как настроить ServicePointManager или Request для правильной работы
РЕДАКТИРОВАТЬ: Это исключение, которое иногда возникает, когда request.GetRequestStream()
выполняется:
at System.Threading.Timer.startTimer(UInt32 dueTime)
at System.Threading.Timer.Change(UInt32 dueTime, UInt32 period)
at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
at System.Threading.ThreadPool.QueueUserWorkItem(WaitCallback callBack, Object state, Boolean IsHttpRequest)
at System.Net.Connection.actionSending()
at System.Net.Connection.changeState(ConnectionState state)
at System.Net.Connection.transitionRequestSent(Event e)
at System.Net.Connection.processEvent(Event e)
at System.Net.Connection.actionRequestSent()
at System.Net.Connection.changeState(ConnectionState state)
at System.Net.Connection.transitionIdle(Event e)
at System.Net.Connection.processEvent(Event e)
at System.Net.Connection.submitRequest(HttpWebRequest request)
at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connGroupName)
at System.Net.HttpWebRequest.SubmitRequest()
at System.Net.HttpWebRequest.finishGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
1 ответ
Я тоже застрял в этом вопросе на пару дней. Наконец, я обнаружил, что если я запустил Fiddler в фоновом режиме, в request.GetRequestStream()
, Это означает, что это связано с пулом соединений, где Fiddler обрабатывает это. Поэтому я провел небольшое исследование и нашел следующую ссылку, которая решила мою проблему:
https://www.telerik.com/blogs/help!-running-fiddler-fixes-my-app-
Также после того, как запрос завершен, убедитесь, что вы также прервали его. Что я сделал, это:
if (webrequest != null) webrequest.Abort();
У меня все работает нормально сейчас.