Подтвердить что ты не робот

HttpWebRequest: запрос был прерван: запрос был отменен

Я работаю над разработкой приложений среднего класса, которые загружают текст в бэкэнд CMS, используя HTTP-запросы для серии дат (обычно 7 за раз). Я использую HttpWebRequest для этого. Кажется, что он работает нормально для первой даты, но когда он начинает вторую дату, я получаю System.Net.WebException: запрос был прерван: запрос был отменен.

Я обыскал и нашел следующие большие подсказки:

http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/0d0afe40-c62a-4089-9d8b-fb4d206434dc

http://www.jaxidian.org/update/2007/05/05/8

http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html

И они не были слишком полезны. Я попытался перегрузить GetWebReuqest, но это не имеет смысла, потому что я не использую эту функцию.

Вот мой код: http://pastebin.org/115268

Я получаю сообщение об ошибке в строке 245 после успешного выполнения хотя бы один раз.

Буду признателен за любую помощь, которую я могу получить, поскольку это последний шаг в проекте, над которым я работал некоторое время. Это мой первый проект С#/VS, поэтому я открыт для любых советов, но я хотел бы сосредоточиться на решении этой проблемы в первую очередь.

БЛАГОДАРЯ!

4b9b3361

Ответ 1

Общим решением, указанным в Интернете, должно быть установлено значение свойства KeepAlive для HttpWebRequest равным false. Это может решить проблему, если основной причиной является то, что соединение, как ожидается, будет повторно использовано, даже если оно было фактически закрыто автоматически через некоторый период времени. Тем не менее, наблюдается постоянное открытие и закрытие соединений.

Другим возможным решением, которое я использовал, когда я столкнулся с этой проблемой, было расширение свойств Timeout: WebRequest.ReadWriteTimeout, WebRequest.Timeout, RequestStream.WriteTimeout и RequestStream.ReadTimeout. Обратите внимание, что это в миллисекундах, поэтому вы можете потребовать, чтобы таймауты составляли 1000 * 60 * 10, чтобы представлять 10 минут (или всего 600000, если вы считаете, что узнаете, что это значит...). Вы можете проверить, является ли это более вероятной причиной проблемы, уменьшив размер файла.

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

Ответ 3

Краткий обзор моей заявки: У меня есть до 16 одинаковых потоков, выполняющих одновременные HTTP-запросы. Каждый из этих потоков запрашивает у разных веб-серверов наряду с уникальными локальными конечными точками. Теперь функция, выполняющая эти вызовы, имеет 3 последовательных HTTP-запроса, чтобы сделать (на тот же веб-сервер) и сделать некоторую агрегацию.

Основываясь на решениях, размещенных в ссылках выше, для меня работала следующая комбинация.

System.Net.ServicePointManager.DefaultConnectionLimit = 200;
System.Net.ServicePointManager.MaxServicePointIdleTime = 2000;
System.Net.ServicePointManager.MaxServicePoints = 1000;
System.Net.ServicePointManager.SetTcpKeepAlive(false, 0, 0);

HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest1.KeepAlive = false;
webRequest1.Timeout = 2000;
//Do other stuff here...
//Close response stream

Thread.Sleep(1000); //This delay seems to help. Obviously very specific to the server

HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest2.KeepAlive = false;
webRequest2.Timeout = 2000;
//Do other stuff here...
//and so on...

Ответ 4

Я поддерживаю веб-службу Azure, которая принимает файлы из мобильного приложения и передает их в хранилище BLOB-объектов Azure, копируя поток входящего запроса в поток исходящего запроса HttpWebRequest, например

using (Stream requestStream = outgoingRequest.GetRequestStream()) 
{ 
    context.Request.InputStream.copyTo(requestStream)
    requestStream.Flush();
    requestStream.Close();
}

Время от времени возникало исключение "Запрос был прерван: запрос был отменен" во время Close() или в конце использования {}, если вы не включили Close(). Я попробовал все предложенные решения выше, и ни одно из них не сработало, пока не нашел действительную причину ошибки, которой я хотел бы поделиться здесь: иногда InputStream входящего запроса обрезается и не содержит полного содержимого файла. Когда этот неполный поток копируется в поток исходящих запросов, исходящий запрос выдает ошибку во время Close() или в конце использования блока {}. Это немного вводит в заблуждение, поскольку причиной является не исходящий запрос, а
неполный поток копируется в него. Чтобы избежать этого, нужно добавить проверку длины потока входящих запросов, сравнивая длину файла, которая должна храниться в заголовке вызывающего приложения, например

    if (context.Request.InputStream.Length != int.Parse(context.Request.Headers["file-length"])) 
    { 
        //handle this case here, e.g.
        context.Response.StatusCode = 500;
        context.Response.StatusDescription = "(500) Internal Server Error";
        context.Response.End();
    }
    else
    {
         //proceed with copying the stream (the first code snippet)
    }