HttpWebRequest: запрос был прерван: запрос был отменен - PullRequest
21 голосов
/ 17 марта 2010

Я работал над разработкой приложения среднего класса, которое загружает текст в серверную часть 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 после успешного выполнения хотя бы один раз.

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

спасибо!

Ответы [ 4 ]

20 голосов
/ 01 июня 2010

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

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

КСТАТИ. Ваш код больше не был на указанном веб-сайте. Возможно, вы захотите включить его в текст вашего поста, если он все еще остается проблемой.

12 голосов
/ 02 ноября 2011

Вот единственное решение, которое работает для меня:

http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx

Эти строки являются ключевыми:

    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(yourUri);
    wr.KeepAlive = false;
    wr.Timeout = System.Threading.Timeout.Infinite;
    wr.ProtocolVersion = HttpVersion.Version10;

А здесь:

wr.AllowWriteStreamBuffering = false;
3 голосов
/ 27 июля 2011

Краткое описание моей заявки: У меня до 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...
1 голос
/ 09 января 2019

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

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

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

    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)
    }
...