Я АБСОЛЮТНЫЙ НУБ C#, так что это мой самый первый проект. Я пишу программу командной строки C%, ввожу URL-адрес, который загружает изображения с веб-сайта галереи, который я часто посещаю. 99% написанного мной кода работает. Моя единственная проблема - это иногда мой код: при попытке получить исходный код веб-страницы иногда загрузка не удалась. 99% того, что я делаю, работает. Этот 1% иногда приводит к сбою моей программы. Я пытаюсь найти способ заставить WebClient.DownloadString повторить попытку загрузки источника страницы в случае ошибки. Несмотря на все вышесказанное, 99% кода написано и работает, поэтому я не буду переписывать его с нуля в другой версии .net. (Предложение, которое я видел на канале разногласий, посвященном кодированию на C#, не помогло ни в малейшей степени)
Это код, который у меня есть для загрузки исходного кода страницы:
static string getPageSource(string url)
{
string pageSource = "";
WebClient client = new WebClient();
pageSource = client.DownloadString(url);
if (pageSource.Length == 0)
{
pageSource = client.DownloadString(url);
}
return pageSource;
}
Сам код работает как есть. Просто всякий раз, когда это терпит неудачу, приложение вылетает.
Пожалуйста, НЕ КРИЧИТЕ НА НАС...
Это похоже на проблему X/Y . Пожалуйста, прочитайте Как создать минимальный воспроизводимый пример. Мы не сможем помочь вам с аварийной программой, если вы не сообщите нам, где она дает сбой.
Очевидно, проблема в коде, который я опубликовал... Иногда, когда он пытается загрузить исходный код страницы, он терпит неудачу, и все приложение выходит из строя. Поэтому мне нужно найти способ сделать "pageSource = client.DownloadString(url);" повторите, если не получится.
Единственное, что вы могли бы сделать, это реализовать некоторую обработку исключений . Посмотри, как ты с этим справишься. В качестве альтернативы есть пакет Polly, но для вашего сценария это может быть излишним.
@YoItsTrev «все приложение кэшируется» никоим образом не делает очевидным, что при этом методе происходит сбой. Как правило, приложения dotnet не «выходят из строя», они выдают исключения, и если они не обрабатываются должным образом, они закрываются более или менее контролируемым образом.
Обратите внимание, что немедленная повторная попытка не всегда является правильной реакцией на сбой. Этот веб-сайт может отклонять ваши запросы из-за того, что вы превысили лимит загрузки, или из-за того, что он в настоящее время перегружен, или из-за какой-либо промежуточной сетевой проблемы, которая может быть или не быть краткосрочным временным явлением.
WebClient
одноразовый. Не забывайте выбрасывать его каждый раз, когда используете. Невыполнение этого требования может в конечном итоге привести к сбою.
Первый шаг — всегда определять причину сбоя приложения. Для этого вы запускаете его в отладчике. В вашем случае, вероятно, выдается исключение в методе DownloadString, поэтому ваша вторая попытка никогда не вызывается.
Это всего лишь предположение, основанное на той ограниченной информации, которую вы предоставили. Судя по вашему посту, вы, видимо, новичок в программировании в целом, да? Вы, очевидно, еще не мыслите как программист, но этого следует ожидать от новичков.
Я рекомендую вам перейти по ссылкам в моем комментарии к вашему исходному сообщению и внимательно прочитать эти документы. Они помогут вам понять, как подходить к задаванию вопросов здесь. Что касается мышления программиста, всегда начинайте с внимательного чтения документации по API, который вы используете:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstring?view=net-8.0
Обратите внимание на список исключений:
Исключения ArgumentNullException Параметр адреса имеет значение null.
WebException URI, сформированный путем объединения BaseAddress и адреса, имеет вид неверный.
-или-
Произошла ошибка при загрузке ресурса.
NotSupportedException Метод был вызван одновременно несколько потоков.
В вашем случае, вероятно, выдается WebException из-за тайм-аута сервера или потому, что он запрещает вам доступ. Возможно, вы превышаете лимит загрузки.
Узнайте, как перехватывать исключения:
Поместите свой код в блок try/catch:
string getPageSource(string url)
{
var pageSource = string.Empty;
try
{
using var client = new WebClient();
pageSource = client.DownloadString(url);
}
catch(WebException ex)
{
Console.WriteLine(ex.Message);
}
catch(Exception ex)
{
Console.WriteLine($"Unexpeccted exception {ex.Message}");
}
return pageSource;
}
Запустите это и сообщите нам, какое исключение было перехвачено, а затем я покажу вам, как правильно выполнить ограниченное количество повторов.
ПРИМЕЧАНИЕ. WebClient устарел и не должен использоваться. Если ваш инструктор советует вам использовать его, используйте его и заглушите его в комментариях о том, как хорошие программисты не будут его использовать и почему.
Я видел попытку в других сообщениях stackoverflow, но разве это не имеет значения? Да, он обработает ошибку, но не решит проблему. Он обработает ошибку, но не решит проблему повторной попытки загрузки исходного кода страницы.
Если вы действительно хотите бесплатной помощи, перестаньте спорить с людьми, которые пытаются помочь вам бесплатно. Опубликуйте вывод исключения, когда вы выполнили поставленную задачу. Если это подтвердит наши предположения, я покажу вам, как правильно выполнять повторные попытки. Не буду тратить время зря, если это окажется неправильным решением.
Я разместил ваш код в своем, но теперь он вылетает КАЖДЫЙ РАЗ, когда я его запускаю.
«он вылетает КАЖДЫЙ РАЗ, когда я его запускаю» ни о чем нам не говорит. Выдает ли это исключение? Пожалуйста, опубликуйте весь текст исключения. Кроме того, я обновил блок кода, включив в него оператор using. Мне удалось его скомпилировать, но я не могу его протестировать, потому что вы никогда не публиковали минимальный воспроизводимый пример.
Если вы не видите вывод консоли из блоков catch, то, вероятно, там не возникает никаких исключений. Это значит, что он падает где-то еще, и нам нужно понять, где и почему.
Как вы запускаете этот код? Если вы запускаете его из IDE, возможно, окно консоли закрывается прежде, чем вы сможете прочитать какой-либо вывод. Попробуйте открыть оболочку cmd, перейти туда, где находится исполняемый файл, и запустить его вручную.
У меня ваш код работает. Выдавало ошибку 404. Мне пришлось прочитать одну строку кода, которую я не добавил в свой код выше: client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML) , как Gecko) Chrome/96.0.4664.93 Safari/537.36"); Я все еще получаю сообщение об ошибке, но оно сообщает слишком много запросов слишком быстро, поэтому я попробую сделать паузу.
Итак, это была проблема X/Y. Вот почему те из нас, кто посидел здесь какое-то время, не принимают слова «он выходит из строя» за чистую монету. Вот почему вам нужно научиться вникать в проблему, прежде чем прийти сюда с просьбой о помощи. Пока вы не поймете фактическую ошибку, вы действительно не поймете, что не так. Повторная попытка тех же ошибочных процессов приведет к увеличению количества ошибок. Тем не менее, вы можете поместить весь этот блок try/catch
в счетный цикл со встроенным вызовом Thread.Sleep(n)
, где n
увеличивается при каждой последующей повторной попытке. Но вам все равно придется иметь дело с неудачами.
Поскольку сбои в сети обычно не устраняются в течение нескольких секунд, повторные попытки обычно должны начинаться через десятки секунд с какого-то сообщения пользователю, а затем быстро сокращаться до нескольких минут с возможностью для пользователя отменить операцию. . Или просто оставьте на усмотрение пользователя, повторять ли вообще попытку, при условии, что вы предоставили ему адекватную информацию о сбое.
Ваша помощь и добавленная мной пауза не привели к сбоям при запуске программы десятки раз без проблем. Спасибо за нашу помощь, я очень ценю это.
@YoItsTrev, спасибо. Не забудьте отметить эту тему как ответившую.
Используя код jwdonahue, я смог получить сообщение об ошибке. В сообщении говорилось, что он пытается получить доступ к серверу слишком быстро. После добавления паузы в код у меня не было сбоев.
Начните с того, что не используйте ЗАГЛАВНЫЕ буквы в названии вопроса, люди воспринимают это как КРИК и не читают дальше.